pin_ptr是一个原生的void *帮助

时间:2010-10-28 17:58:24

标签: 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 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。 WOOPS。我忘了将指针pin_ptr给文件。

问题

当我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 个答案:

答案 0 :(得分:2)

这没有任何意义。您只能固定托管对象,PDF_LoadDoc()的返回值肯定对我来说不像托管对象。同样适用于 result ,它不是托管array<WCHAR>,只是在堆栈帧上分配的普通vanilla C数组。不幸的是,pin_ptr&lt;&gt;不抱怨这个。

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