title: Force CCW Garbge Collection
body: <p>In an C++ unmamaged project an external(*) managed DLL is used via <a href="https://docs.microsoft.com/en-us/dotnet/framework/interop/com-callable-wrapper" rel="nofollow noreferrer">COM Callable Wrapper (CCW)</a> (Registered with RegAsm). But there is a memory leak: Managed memory was never cleaned up.</p>
  
  <p>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#). </p>
  
  <p>In an minimal example the .Net DLL works fine. Maybe the GC got confused with using managed Code with different ways?</p>
  
  <p><strong>How do I force an Garbage Collection of the CCW?</strong></p>
  
  <p>The following code in an existing Wrapper did not work:</p>
  
  <pre><code>    __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-&gt;Message);
          }
          catch (ArgumentNullException^ e) {
              System::Diagnostics::Debug::WriteLine(e-&gt;Message);
          }
          catch (Exception^ e) {
              System::Diagnostics::Debug::WriteLine(e-&gt;Message);
          }
      }
  </code></pre>
  
  <p>ArgumentException in "FinalReleaseComObject" -> No COM Object. In Debugger, the object "obj" looks fine. Structure, data, all OK.</p>
  
  <p>The following code will run, but have no effect:</p>
  
  <pre><code>    __declspec(dllexport) void ExecuteCcwGcWrapper(void* ComObject)
      {
          IntPtr ptr(ComObject);
          while (System::Runtime::InteropServices::Marshal::Release(ptr) &gt; 0);
          //System::GC::AddMemoryPressure(0x7FFFFFFF);
          System::GC::Collect();
          //System::GC::WaitForFullGCComplete();
          System::GC::WaitForPendingFinalizers();
      }
  </code></pre>
  
  <p>(* I don't have access to the sources)</p>