【发布时间】:2010-11-20 23:17:10
【问题描述】:
我有一个用 C++ 编写的进程外 COM 服务器,它由一些 C# 客户端代码调用。服务器接口之一上的方法向客户端返回一个大的 BSTR,我怀疑这会导致内存泄漏。该代码有效,但我正在寻求有关编组 BSTR 的帮助。
简单一点,服务端方法的IDL是
HRESULT ProcessRequest([in] BSTR request, [out] BSTR* pResponse);
实现如下:
HRESULT MyClass::ProcessRequest(BSTR request, BSTR* pResponse)
{
USES_CONVERSION;
char* pszRequest = OLE2A(request);
char* pszResponse = BuildResponse(pszRequest);
delete pszRequest;
*pResponse = A2BSTR(pszResponse);
delete pszResponse;
return S_OK;
}
A2BSTR 在内部使用 SysAllocStringLen() 分配 BSTR。
在 C# 客户端中,我只需执行以下操作:
string request = "something";
string response = "";
myserver.ProcessRequest(request, out response);
DoSomething(response);
这是可行的,因为请求字符串被发送到 COM 服务器,正确的响应字符串被返回给 C# 客户端。但是每次到服务器的往返都会在 server 进程中泄漏内存。 crt 泄漏检测支持显示 crt 堆上没有明显的泄漏,所以我怀疑泄漏是用 IMalloc 分配的。
我在这里做错了吗?我发现模糊的 cmets 说“必须使用 CoTaskMemAlloc 分配所有参数,否则互操作编组器不会释放它们”但没有详细信息。
安迪
【问题讨论】:
-
感谢这个问题和答案,因为我将 BSTR 与 ATL COM 对象和 C++ 一起使用。我发现的一件事是,如果您在 IDL 中将 BSTR * 指定为 [out],那么如果传递的 BSTR * 已被初始化,您将获得内存泄漏。因此,您需要在 IDL 文件中将 BSTR * 声明为 [in,out]。见msdn.microsoft.com/en-us/library/bdyd6xz6.aspx