In an C++ unmamaged project an external(*) managed DLL is used via COM Callable Wrapper (CCW) (Registered with RegAsm). But there is a memory leak: Managed memory was never cleaned up.
Background: The C++ project is an old-grown 32 bit program. It loads several DLLs, a few of them are managed DLLs (written in C#).
In an minimal example the .Net DLL works fine. Maybe the GC got confused with using managed Code with different ways?
How do I force an Garbage Collection of the CCW?
The following code in an existing Wrapper did not work:
__declspec(dllexport) void ExecuteCcwGcWrapper(void* ComObject)
{
IntPtr ptr(ComObject);
Object^ obj = System::Runtime::InteropServices::Marshal::GetObjectForIUnknown(ptr);
try {
System::Runtime::InteropServices::Marshal::FinalReleaseComObject(obj);
}
catch (ArgumentException^ e) {
System::Diagnostics::Debug::WriteLine(e->Message);
}
catch (ArgumentNullException^ e) {
System::Diagnostics::Debug::WriteLine(e->Message);
}
catch (Exception^ e) {
System::Diagnostics::Debug::WriteLine(e->Message);
}
}
ArgumentException in "FinalReleaseComObject" -> No COM Object. In Debugger, the object "obj" looks fine. Structure, data, all OK.
The following code will run, but have no effect:
__declspec(dllexport) void ExecuteCcwGcWrapper(void* ComObject)
{
IntPtr ptr(ComObject);
while (System::Runtime::InteropServices::Marshal::Release(ptr) > 0);
//System::GC::AddMemoryPressure(0x7FFFFFFF);
System::GC::Collect();
//System::GC::WaitForFullGCComplete();
System::GC::WaitForPendingFinalizers();
}
(* I don't have access to the sources)