0

I have COM-function that returns a BSTR. and its used like that:

The interface:

interface ITexts : IDispatch
{
    [id(5)] HRESULT GetText([in] long Number, [in] long LangID, [out,retval] BSTR* pText);
};

The implementation

STDMETHODIMP CTexts::GetText(long Number, long LangID, BSTR *pText)
{
    CString sDummyValue = _T("gettext"); //just for testing
    sDummyValue.SetSysString(pText);
    return S_OK;
}

And the client

CString RITexts::GetText(long Number, long LangID)
{
    CString result;
    static BYTE parms[] = VTS_I4 VTS_I4;
    InvokeHelper(0x5, DISPATCH_METHOD, VT_BSTR, (void*)&result, parms, Number, LangID);
    return result;
}

When running as debug-build Visual Studio doesn't complain but DeLeaker (a memory leak monitoring tool) thinks there is a memory leak:

OLEAUT32.dll!SysReAllocStringLen 76543120
mfc140ud.dll!ATL::ChTraitsCRT<wchar_t>::ReAllocSysString Line 815 + 0xe bytes 7a2d0012
mfc140ud.dll!ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >::SetSysString Line 2288 + 0x16 bytes 7a2d0a39
(-> ComClass) LangSupp.dll!CTexts::GetText Line 343 + 0x9 bytes 7b1698b2
OLEAUT32.dll!DispCallFunc + 0x16d bytes 7655840d
OLEAUT32.dll!CTypeInfo2::Invoke + 0x2e6 bytes 7653aca6
LangSupp.dll!ATL::CComTypeInfoHolder::Invoke Line 4204 + 0x31 bytes 7b15c056
LangSupp.dll!ATL::IDispatchImpl<ITexts,&IID_ITexts,&LIBID_LANGSUPPLib,1,0,ATL::CComTypeInfoHolder>::Invoke Line 5163 + 0x2a bytes 7b15bfa2
mfc140ud.dll!COleDispatchDriver::InvokeHelperV Line 399 + 0x7 bytes 7a1e6d6b
mfc140ud.dll!COleDispatchDriver::InvokeHelper Line 554 + 0x1d bytes 7a1e6597
(-> Client) Managers.dll!RITexts::GetText Line 104 + 0x1b bytes 7ac2ce3a 

So is this a false positive from DeLeaker or do I miss something about freeing the string?

Artem Razin
  • 1,234
  • 8
  • 22
suriel
  • 191
  • 1
  • 10

2 Answers2

0

The call InvokeHelper is incorrect.

The type of result should be either BSTR or even better to use a wrapper like _bstr_t or CComBSTR to ensure that the memory allocated for the BSTR will be freed.

Artem Razin
  • 1,234
  • 8
  • 22
0

Server is correct, client is wrong. You want to use a variant type to get the result from an automation call. Try:

CString RITexts::GetText(long Number, long LangID)
{
    static BYTE parms[] = VTS_I4 VTS_I4;
    _variant_t vResult;
    InvokeHelper(0x5, DISPATCH_METHOD, VT_VARIANT, (void*)&vResult, parms, Number, LangID);
    CString result((wchar_t*) vResult.bstrVal); // should have error checking of your result and type
    return result;
}
Joseph Willcoxson
  • 5,853
  • 1
  • 15
  • 29
  • thank you very much. I just dont know why VS is generation such code for years now and I don't see any affects from it. posted another question about his here: https://stackoverflow.com/questions/63378035/impact-of-memoryleak-in-com-call – suriel Aug 12 '20 at 13:54