Memory leak using COM Interop to Call managed DLL from C++

EDN Admin

Well-known member
Joined
Aug 7, 2010
Messages
12,794
Location
In the Machine
I have a piece of C++ code that interacts with a managed DLL which performs some web service calls on its behalf and returns a struct of the data that is returned from the Web Services calls.
Unfortunately, I seem to be leaking memory, and I cant seem to figure out why. I have follwed the example code from Microsoft, but still I seem to be leaking. I was wondering if it is necesary to free the structs that are returned from COM explicitliy,
even though I have not found mention of having to do so in the articles I have read. I know that the two bits of memory are separate, and we have confirmed that everythign is getting GCd on the managed side. We also implemented an explicit Dispose()
method on the managed side to force GC and have verified that is working.
The code I have is as follows:
<div style="color:Black;background-color:White; <pre>
BOOL Class::MyFunction()
{
HRESULT hr;
CoInitialize(NULL);

Interop::IInteropPtr pIInterop;
pIInterop = <span style="color:Blue; new Interop::IInteropPtr(__uuidof(Interop::InteropClass));

InteropTypes::InteropListing listing;
listing = pIInterop->IGetContents(); <span style="color:Green; // listing is a struct

hr = S_OK;
<span style="color:Blue; for (<span style="color:Blue; int i = 0; SUCCEEDED(hr) && i < listing.Count; i++)
{
<span style="color:Blue; long lBound, uBound;
SafeArrayGetLBound( listing.VaultNames, 1, &lBound);
SafeArrayGetUBound( listing.VaultNames, 1, &uBound);
<span style="color:Blue; long j = i;

<span style="color:Green; // BSTRING representations of strings for extraction from COM
BSTR bDspName;
BSTR bVuid;
BSTR bRootTkn;
BSTR bModDate;

memset(&bDspName, 0, <span style="color:Blue; sizeof(BSTR));
memset(&bVuid, 0, <span style="color:Blue; sizeof(BSTR));
memset(&bRootTkn, 0, <span style="color:Blue; sizeof(BSTR));
memset(&bModDate, 0, <span style="color:Blue; sizeof(BSTR));


<span style="color:Green; // BSTR and WCHAR* so you can just copy from one to the other
<span style="color:Green; // http://www.codeguru.com/forum/archive/index.php/t-150671.html

SafeArrayGetElement(listing.VaultNames, &j, &bDspName); <span style="color:Green; // Get the display name
SafeArrayGetElement(listing.VaultUuids, &j, &bVuid); <span style="color:Green; // Get the UUID
SafeArrayGetElement(listing.VaultRootTokens, &j, &bRootTkn);

PWCHAR wcURL = L<span style="color:#A31515; "NO URL"; <span style="color:Green; // These are not downloadable, so no URLs.
PWCHAR wcSize = L<span style="color:#A31515; ""; <span style="color:Green; // These dont have a size attribute
bModDate =L<span style="color:#A31515; ""; <span style="color:Green; // These dont have modified dates, so make them the null string

BOOL isV = <span style="color:Blue; true;
BOOL isF = <span style="color:Blue; true;

NewItem(bDspName, isV, isF, bVuid, bRootTkn, bRootTkn, bModDate, wcSize, wcURL);
}
}

hr = pIInterop->Dispose(); <span style="color:Green; // This calls some dispose methods on the managed side and causes the garbage to be collected
<span style="color:Green; // This is working, and the C# side is not leaking memory.


CoUninitialize();

<span style="color:Blue; return hr;
}


[/code]
<br/>
Is it required to somehow explicitly free the memory on the native side , i.e. free the pointer to the Managed DLL or the struct that holds the returned values ? None of the example code I have found does this, but I am curious whether anyone has experience
with this ? I know COM Interop can be leaky if you are not very precise in how you do the marshalling, so any help would be appreciated.


Thanks in advance,<br/>
<br/>
JT.

View the full article
 
Back
Top