Memory pin_ptr本机void*帮助 设置

Memory pin_ptr本机void*帮助 设置,memory,c++-cli,mixed-mode,pin-ptr,Memory,C++ Cli,Mixed Mode,Pin Ptr,我有一个PDF API,它有一个下面定义的本机函数 typdef void* PDF_DOCUMENT; unsigned long PDF_GetMetaText(PDF_DOCUMENT document, const char tag, void* buffer, unsigned long bufferle

我有一个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包装函数中调用上述代码,它将返回正确的字符串,但在调用PDF_CloseDoc时抛出AccessViolationException。呜呜声。我忘了把指针钉在文件上

问题 当我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);
}
String^Wrapper::GetCreator(String^filename)
{
WCHAR缓冲区[32];
void*pdoc=PDF_LoadDoc(SystemStringToCStr(文件名));
pin_ptr p=&pdoc;//已添加
int numPages=PDF_GetMetaText(p,“创建者”,缓冲区,32);
PDF_CloseDocument(p);//不会崩溃,但在这一行,缓冲区是一个空字符串
返回新字符串(缓冲区);
}
我还尝试固定缓冲区[0],但这会导致GetMetaText出现accessviolation异常

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

这没有任何意义。您只能锁定托管对象,PDF_LoadDoc()的返回值在我看来肯定不像托管对象。结果也是一样,它不是一个托管的
数组
,只是一个在堆栈框架上分配的普通C数组。不幸的是,pin_ptr并没有对此抱怨


如果代码正在踩踏堆栈帧,则结果数组只能得到“空”。可以通过在第一个元素上设置数据断点进行诊断。Fwiw,SystemStringToCStr()看起来像一个候选者。如果不在某处释放本机字符串的缓冲区,这将无法工作。另一个候选者是PDF API函数声明。请注意ESP寄存器的值,并确保其不变。如果是这样,堆栈就会变得不平衡,因为您没有正确的调用约定。这通常是DLL导出的stdcall。

这是一个很好的答案,我即将接受,但我有一个问题。在VisualStudio2008中,调用函数时如何查看ESP寄存器中的内容?PDF_GetMetaText是我使用GetProcAddress指定的函数指针。我用u stdcall.Debug+Windows+寄存器显式声明它。这绝对像调用约定不匹配一样令人震惊。我认为正确的答案是:这是API中的一个bug。当我试图在iTextSharp(开放源代码库)中解析PDF时,它在试图读取PDF外部参照部分时抛出“InvalidPDException”。当我把“好”的PDF放到PDF_GetMetaText中时,效果很好。当pdf为“坏”时,它会将pdoc指向的地址更改为,但我的WCHAR缓冲区会用正确的字符串填充。此外,pdoc的地址在一个错误的呼叫后发生变化。我将把这个标记为回答,谢谢你把我推向正确的方向。