我正在尝试编写一些从非托管DLL调用方法的C#代码。dll中的函数原型为:extern "C" __declspec(dllexport) char *foo(void);在C#中,我首先使用:[DllImport(_dllLocation)]public static extern string foo();它似乎在表面上起作用,但是在运行时出现内存损坏错误。我认为我指的是碰巧是正确的但已经被释放的内存。我尝试使用称为“ P / Invoke Interop Assistant”的PInvoke代码生成实用程序。它给了我输出:[System.Runtime.InteropServices.DLLImportAttribute(_dllLocation, EntryPoint = "foo")]public static extern System.IntPtr foo();它是否正确?如果是这样,如何在C#中将此IntPtr转换为字符串?
2 回答

ABOUTYOU
TA贡献1812条经验 获得超5个赞
您必须将此作为IntPtr返回。从PInvoke函数返回System.String类型需要非常小心。CLR必须将内存从本机表示形式转移到托管表示形式。这是一个容易且可预测的操作。
但是,问题在于如何处理从foo()返回的本机内存。CLR假设以下两个有关直接返回字符串类型的PInvoke函数的项目
本机内存需要释放
本机内存是通过CoTaskMemAlloc分配的
因此,它将封送字符串,然后在本机内存blob上调用CoTaskMemFree。除非您实际上使用CoTaskMemAlloc分配了此内存,否则充其量只会导致应用程序崩溃。
为了在这里获得正确的语义,您必须直接返回IntPtr。然后使用Marshal.PtrToString *以获得托管的String值。您可能仍然需要释放本机内存,但这将取决于foo的实现。
没有找到匹配的内容?试试慕课网站内搜索吧
- 2 回答
- 0 关注
- 473 浏览
添加回答
举报
0/150
提交
取消