0

I have a single-threaded application that uses COM objects. At the beginning I in effect call CoInitialize(0) twice - once in my code and the second time in the code of another subsystem of the application. The first call returns S_OK, the second returns S_FALSE - exactly as MSDN says.

When the application stops it calls CoUninitialize() twice but between those calls it tries to call methods of some COM objects - those calls just crash with access violation because I suppose the COM objects are finalized and released at the first call to CoUnitialize(). If I remove the duplicating calls to CoInitialize()/CoUnitialize() it works allright.

But why is this? MSDN says I can call CoInitialize() repeatedly and must only pair those calls with the matching number of CoUnitialize() calls.

Why are COM objects finalized at the first call to CoUninitialize().

sharptooth
  • 167,383
  • 100
  • 513
  • 979
  • Out of curiosity why is it you *want* it to work the way you have it implemented - why not just one pair? – Ruddy Jan 28 '10 at 11:59
  • That other subsystem is sometimes used by other programs and it's ugly to demand that they call CoInitialize(), so the subsystem calls it itself before creating the first COM object it will use. – sharptooth Jan 28 '10 at 12:03
  • I can't say *why* it won't work, but i've seen similar issues and always went back to having just one CoUninitialize - no doubt you've already considered (as a hack-workaround) keeping track of the CoInitialize returning S_FALSE and not calling CoUnitialize. – Ruddy Jan 28 '10 at 12:20
  • In my experience it is unwise for individual components to initialize COM themselves, specifically because you run into issues like this. It is much better design to force the client to initialize COM. – Luke Jan 28 '10 at 15:10
  • I looked on XP SP3, CoUninitialize is reference counted, other than calling NotifyInitializeSpies (empty list on my machine), it only decrements the reference count on the first call. Set a break point on _CoUninitialize@0 to verify some else isn't calling it an extra time. I assume you're not calling it right after CoInit() returns S_FALSE. – Tony Lee Mar 03 '10 at 17:17

1 Answers1

0

sounds like you're doing it correct, however, check to be sure your couninitialize calls are done after the main window for the app has closed and after the message loop for that window has run finished.

Don Dickinson
  • 6,200
  • 3
  • 35
  • 30