从C ++方法接收char *,转换为托管字符串,然后释放内存

时间:2013-05-28 13:23:17

标签: c# c++ memory-management

我需要从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;
}

1 个答案:

答案 0 :(得分:2)

一般来说,如何释放从C ++函数返回的任意指针是不可能的。指针生成的方式有很多种(newmallocVirtualAlloc,当你在Windows上时,等等。没有办法通过检查确定指针来自哪一个,并且使用错误的释放函数是一个错误(这可能会使您的进程崩溃)。此外,即使您知道要调用哪个函数,您的代码也可能会链接到不同版本的语言运行时库 - 因此您可能正在调用freedelete,但这是一个不兼容的版本。< / p>

正常过程适用于执行分配的库,以提供相应的释放函数,以便适当地释放分配的内存。如果你使用的图书馆没有这个,你只需要尝试他们告诉你的内容,如果它不起作用就跟进。