代码之家  ›  专栏  ›  技术社区  ›  Tom Fobear

Pin_ptr a native void*帮助

  •  1
  • Tom Fobear  · 技术社区  · 15 年前

    设置

    我有一个PDF API,它具有下面定义的本机函数。

    typdef void* PDF_DOCUMENT;
    unsigned long PDF_GetMetaText(PDF_DOCUMENT document,
                                  const char tag, 
                                  void* buffer, 
                                  unsigned long bufferlen)
    
    //Calling it "natively" in C++/CLI function to get the PDF Creator tag
    WCHAR result[32];
    void* pdoc = PDF_LoadDoc("C:\test.pdf");
    int numChars = PDF_GetMetaText(pdoc, "Creator", result, 32);
    PDF_CloseDoc(pdoc);
    

    如果我在C++/CLI包装器函数中调用上面的代码,它会返回正确的字符串,但是当我调用PDFYCouthEdoc时抛出一个Access违规。胡扯。我忘了把指针钉在文件上。

    问题

    当我pin_ptr pdoc时,我可以成功地调用这些本机函数,但是当pdf_getmetatext返回时,缓冲区不再包含我的字符串。

    String^ Wrapper::GetCreator(String^ filename)
    {
       WCHAR buffer[32];
       void *pdoc = PDF_LoadDoc(SystemStringToCStr(filename));
       pin_ptr<void*> p = &pdoc; //added
       int numPages = PDF_GetMetaText(p, "Creator", buffer, 32);
       PDF_CloseDocument(p); //doesnt crash, but at this line buffer is an empty string
    
       return gcnew String(buffer);
    }
    

    我还尝试固定缓冲区[0],但这会导致getmetatext处发生访问冲突异常。

    问题

    我不能说GetMetaText中发生了什么,所以我不确定PDOC发生了什么。对以上代码有什么建议吗?

    1 回复  |  直到 15 年前
        1
  •  2
  •   Hans Passant    15 年前

    这没有任何意义。您只能固定托管对象,PDF的返回值loudDoc()在我看来不像托管对象。同样的道理 结果 ,它不是管理的 array<WCHAR> ,只是在堆栈帧上分配的普通C数组。不幸的是,Pin<>没有对此抱怨。

    这个 结果 只有当代码正在踩踏堆栈帧时,数组才能获得“空”。可以通过在第一个元素上设置数据断点进行诊断。fwiw,systemstringtocstr()看起来像一个候选者。如果不释放本地字符串的缓冲区,这将无法工作。另一个候选函数是PDF API函数声明。注意ESP寄存器的值,确保它不会改变。如果是这样,那么栈就会失衡,因为您没有适当的调用约定。通常是dll导出的stdcall。

    推荐文章