Tengo un servidor COM fuera de proceso escrito en C++, que es llamado por algún código de cliente C#. Un método en una de las interfaces del servidor devuelve un BSTR grande al cliente, y sospecho que esto está causando una pérdida de memoria. El código funciona, pero estoy buscando ayuda para organizar BSTRs.BSTR de clasificación de C++ a C# con interoperabilidad COM
Simplificando un poco, el IDL para el método de servidor es
HRESULT ProcessRequest([in] BSTR request, [out] BSTR* pResponse);
y la puesta en práctica se parece a:
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 asigna internamente el BSTR usando SysAllocStringLen().
En el cliente de C# simplemente hacer lo siguiente:
string request = "something";
string response = "";
myserver.ProcessRequest(request, out response);
DoSomething(response);
Esto funciona, en el que las cadenas de solicitud se envían al servidor COM y cadenas de respuesta correctas son devueltos al cliente C#. Pero cada viaje de ida y vuelta al servidor pierde memoria en el proceso del servidor. El soporte de detección de fugas crt no muestra fugas significativas en el montón crt, por lo que sospecho que la fuga se asignó con IMalloc.
¿Estoy haciendo algo mal aquí? He encontrado comentarios vagos de que "todos los parámetros deben asignarse con CoTaskMemAlloc, de lo contrario el marshaller de interoperabilidad no los liberará", pero sin detalles.
Andy
Gracias por esta pregunta y las respuestas que estoy usando BSTR con un objeto COM de ATL y C++. Una cosa que encontré fue que si especifica un BSTR * como [out] en el IDL, si se ha inicializado el BSTR * se obtendrá una fuga de memoria. Por lo tanto, debe declarar el BSTR * como [in, out] en el archivo IDL. Consulte http://msdn.microsoft.com/en-us/library/bdyd6xz6.aspx –