是否需要释放用作函数参数的托管 BSTR

本文关键字:参数 BSTR 函数 释放 是否 | 更新日期: 2023-09-27 18:34:00

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

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

谢谢

是否需要释放用作函数参数的托管 BSTR

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

不应释放字符串,因为调用方可能会重用传递的数据,如果释放,则可能会出现错误。原因是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(...)我们正在重现您的情况。如您所见,调用方负责在被调用方外部分配/解除分配参数字符串。