在将Ctring从C ++编组到C#时,如何(如果需要)释放动态内存?

时间:2010-04-28 15:04:20

标签: c# c++ memory-management dynamic cstring

我在C ++端有CString cs,在C#端有IntPtr ip,它包含通过编组机制的cs值。

然后,我只需要将String作为Marshal.PtrToStringAnsi(ip),一切正常,但我想知道我是否应该如何删除ip占用的非托管内存,即cs?

2 个答案:

答案 0 :(得分:1)

非托管代码分配的非托管内存只能由非托管代码释放。因此,您需要添加另一个非托管函数,该函数将获取指向已分配字符串的指针并释放内存。然后,应该在使用字符串完成后从托管代码调用此函数。

示例:

class Program
{
    [DllImport("test.dll")]
    static extern IntPtr GetString();

    [DllImport("test.dll")]
    static extern IntPtr FreeString(IntPtr ptr);

    static void Main()
    {
        IntPtr ptr = GetString();
        try
        {
            var str = Marshal.PtrToStringAnsi(ptr);
            // work with the string
        } 
        finally 
        {
            if (ptr != IntPtr.Zero)
            {
                FreeString(ptr);
            }
        }
    }
}

答案 1 :(得分:1)

你不能,你不知道非托管代码使用什么分配器来创建CString实例。而且,你必须调用CString析构函数,你不能得到它的地址。

如果将这个CString对象作为从C#调用的C ++函数的函数返回值返回,那么你已经死了。你的问题并不清楚。你将有一个无法控制的内存泄漏。需要用C ++ / CLI编写的包装器来解决该问题。作为函数返回值返回的字符串必须由CoTaskMemAlloc()分配,以便由P / Invoke编组器正确清理。没有C ++代码可以做到这一点。