gpt4 book ai didi

c# - 使用 COM 互操作将 BSTR 从 C++ 编码到 C#

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:46:58 24 4
gpt4 key购买 nike

我有一个用 C++ 编写的进程外 COM 服务器,它由一些 C# 客户端代码调用。服务器接口(interface)之一上的方法向客户端返回一个大的 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# 客户端。但是到服务器的每次往返都会在服务器 进程中泄漏内存。 crt 泄漏检测支持显示 crt 堆上没有明显的泄漏,所以我怀疑泄漏是由 IMalloc 分配的。

我是不是做错了什么?我发现模糊的评论,“所有输出参数必须使用 CoTaskMemAlloc 分配,否则互操作编码器不会释放它们”,但没有详细信息。

安迪

最佳答案

我没有发现您的代码存在明显的问题。建议您修改 ProcessRequest 方法以排除 COM 互操作作为泄漏源:

HRESULT MyClass::ProcessRequest(BSTR request, BSTR* pResponse)
{
*psResponse = ::SysAllocStringLen(L"[suitably long string here]");
return S_OK;
}

我怀疑不会泄漏,在这种情况下,您已将泄漏范围缩小到您的代码。

我还注意到 OLE2A 在堆栈上分配内存,因此您不仅不应该删除 pszRequest,而且根本不应该使用 OLE2A,因为堆栈溢出的可能性。参见 this article寻找更安全的替代品。

我还建议您将 A2BSTR 替换为::SysAllocString(CA2W(pszResponse))

关于c# - 使用 COM 互操作将 BSTR 从 C++ 编码到 C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1300122/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com