4

如果我从非托管代码调用了托管 COM 接口,我是否负责在使用后释放内存,还是由垃圾回收处理?

 public void WriteOutFile([In] [MarshalAs(UnmanagedType.BStr)] String data)
 {
      File.WriteAllText(fileName, data);
      //do I need the line below??
      Marshal.FreeBSTR(data);
 }

谢谢

4

2 回答 2

4

编组涉及将数据从非托管内存复制到托管内存。您不需要释放该string实例,因为它是一个托管对象。但是如果在回调调用之前在本机代码中分配内存,则需要在回调调用之后释放本机代码中的内存。

于 2012-05-12T08:25:35.813 回答
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(...)在您的托管代码中实现了我们正在重现您的情况。如您所见,调用者负责在被调用者之外分配/释放参数字符串。

于 2012-05-12T08:24:52.210 回答