用于返回char的C函数的PInvoke

我正在尝试编写一些从非托管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转换为字符串?


繁华开满天机
浏览 474回答 2
2回答

ABOUTYOU

您必须将此作为IntPtr返回。从PInvoke函数返回System.String类型需要非常小心。CLR必须将内存从本机表示形式转移到托管表示形式。这是一个容易且可预测的操作。但是,问题在于如何处理从foo()返回的本机内存。CLR假设以下两个有关直接返回字符串类型的PInvoke函数的项目本机内存需要释放本机内存是通过CoTaskMemAlloc分配的因此,它将封送字符串,然后在本机内存blob上调用CoTaskMemFree。除非您实际上使用CoTaskMemAlloc分配了此内存,否则充其量只会导致应用程序崩溃。为了在这里获得正确的语义,您必须直接返回IntPtr。然后使用Marshal.PtrToString *以获得托管的String值。您可能仍然需要释放本机内存,但这将取决于foo的实现。
打开App,查看更多内容
随时随地看视频慕课网APP