我需要从C#调用第三方非托管C ++ dll。 C ++函数返回一个char *。我已经想出如何将它转换为C#中的托管字符串。但我不知道是否需要释放内存。以下代码有效,但Marshal.FreeHGlobal(p)抛出“句柄无效”。那么我是否需要释放内存,如果是,那该怎么办?
[DllImport("abc.dll", EntryPoint = "?GetVersion@ABC@@QEAAPEADXZ", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
private static extern unsafe char* GetVersionRaw();
public static unsafe string GetVersion()
{
char* x = Abc.GetVersionRaw(); // call the function in the unmanaged DLL
IntPtr p = new IntPtr(x);
string s = Marshal.PtrToStringAnsi(p);
Marshal.FreeHGlobal(p);
return s;
}
答案 0 :(得分:2)
一般来说,如何释放从C ++函数返回的任意指针是不可能的。指针生成的方式有很多种(new
,malloc
,VirtualAlloc
,当你在Windows上时,等等。没有办法通过检查确定指针来自哪一个,并且使用错误的释放函数是一个错误(这可能会使您的进程崩溃)。此外,即使您知道要调用哪个函数,您的代码也可能会链接到不同版本的语言运行时库 - 因此您可能正在调用free
或delete
,但这是一个不兼容的版本。< / p>
正常过程适用于执行分配的库,以提供相应的释放函数,以便适当地释放分配的内存。如果你使用的图书馆没有这个,你只需要尝试他们告诉你的内容,如果它不起作用就跟进。