我需要释放作为函数参数使用的托管BSTR吗?

4
如果我从非托管代码调用了一个被管理的COM接口,那么在使用完后,我需要负责释放内存吗?还是由垃圾回收器来处理?
 public void WriteOutFile([In] [MarshalAs(UnmanagedType.BStr)] String data)
 {
      File.WriteAllText(fileName, data);
      //do I need the line below??
      Marshal.FreeBSTR(data);
 }

谢谢

2个回答

4

Marshalling涉及将数据从非托管内存复制到托管内存。由于string实例是托管对象,因此无需释放它。但如果在回调调用之前在本地代码中分配了内存,则需要在回调调用后在本地代码中释放内存。


3
您不应该释放字符串,因为调用者可能会重新使用传递的数据,如果您释放了它,可能会导致故障。原因是FreeBSTR没有使用任何引用计数机制,只是简单地调用SysFreeString,而这个函数假定字符串是使用Sys(Re)Alloc...之一分配的,而在托管代码中,您并不知道这种情况发生过。这里示例很有趣,想象一下从链接中调用您的非托管代码是这样的:(来自上面链接的代码):
// shows using the Win32 function 
// to allocate memory for the string: 
BSTR bstrStatus = ::SysAllocString(L"Some text");
if (bstrStatus != NULL)
{
   pBrowser->put_StatusText(bstrStatus);
   // Free the string:
   ::SysFreeString(bstrStatus);
}

如果您在托管代码中实现了put_StatusText(...),我们将重现您的情况。正如您所看到的,调用方负责分配/释放参数字符串,被调用者之外。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接