2

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

然后,我只是得到需要的 String 作为 Marshal.PtrToStringAnsi(ip) 并且一切正常,但我想知道我是否应该以及如果应该,我怎样才能删除 ip 占用的非托管内存,即 cs?

4

2 回答 2

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);
            }
        }
    }
}
于 2010-04-28T15:07:45.977 回答
1

你不能,你不知道非托管代码使用什么分配器来创建 CString 实例。此外,您必须调用 CString 析构函数,您无法获取其地址。

如果此 CString 对象作为您从 C# 调用的 C++ 函数的函数返回值返回,那么您就死定了。从你的问题看不清楚。您将遇到无法控制的内存泄漏。需要使用 C++/CLI 编写的包装器来解决该问题。作为函数返回值返回的字符串必须由 CoTaskMemAlloc() 分配,才能被 P/Invoke 编组器正确清理。没有 C++ 代码会这样做。

于 2010-04-28T15:16:56.290 回答