2012-05-12 31 views
4

如果我已托管从非托管代码调用的COM接口,我是否负责在使用后释放内存或将其处理为垃圾回收?我是否需要释放托管的BSTR作为函数参数

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

感谢

回答

3

你不应该释放字符串,因为主叫方可以潜在地重用传递的数据,如果你释放它可能会出现故障。原因在于FreeBSTR不使用任何引用计数机制,只是简单地调用SysFreeString,顺便说一下,假定该字符串被分配了函数Sys(Re)Alloc...之一,这是您在托管代码中不知道的情况。 的例子shown here有趣的是,IMAGIN的非托管代码打电话给你是这个(从链接前):

// 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); 
} 

,并已在托管代码imlemented put_StatusText(...)我们重现您的情况。正如你所看到的是调用者负责分配/取消分配参数字符串以外的被调用者。

4

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

相关问题