CoUninitialize() and CComPtr<> object lifetimes

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



I have tracked down a bug involving object lifetimes to a quirk in CComPtr<>
that is related to CoInitialize() and CoUninitialize(). It seems that the
destructor for my CComPtr<> is not being called until CoUnitialize() is
called, even though the variable itself has gone out of scope. It does not
help that CoInitialize() is being called somewhere in the app framework.

Here is the issue, it appears in an OnInitDialog() fxn for a modal dialog:

LRESULT OID( ... blah ...)
{
//CoInitialize() has already been called ...
CComPtr<IMyOb> pOb = 0; //local declaration of ccomptr, OK
HRESULT hr = CoCreateInstance( ..., inproc|local server, IID_IMyOb, &pOb
....);
..error check on hr ...
pOb->foo();
return SOMETHING;
}

The object housing for MyOb has a CComModule-derived object that does some
important initialization in DllMain(PROCESS_ATTACH), and deinitializes in
DllMain(PROCESS_DETACH). The _Module object is globally declared in DllMain,
using the "old" ATL form (the project was started in VC++ 6.0).

With the code above, I would expect that the dtor for _Module would fire
right after the return() statement, because pMyOb has the last ref on any
object in the DLL. Instead, it fires when I kill the app by dismissing this
main dialog. Strange.

So, I took the code above and tried to 'force' the issue this way:

LRESULT OID( ... blah ...)
{
//CoInitialize() called again here ...
CoInitialize(0);

//we will force pOb out-of-scope no matter what!!
{

CComPtr<IMyOb> pOb = 0; //local declaration of ccomptr, OK
HRESULT hr = CoCreateInstance( ..., inproc|local server, IID_IMyOb,
&pOb ...);
..error check on hr ...
pOb->foo();
}

CoUninitialize(); //paired with CoInit() above ...

return SOMETHING;
}

This does not change anything at all, except that CoInitialize(0) returns
S_FALSE to tell me it has already been called.


So, I struck the CoInitialize(0), and left in the CoUninit(), and ran again.
This time the dtor for _Module fired as soon as CoUninit() was called. Of
course this left my program with CoInit() uncalled and subsequent COM calls
fail.

This I can fix, but cannot understand. What is going on with this DLL? Why
is it hanging around after all refs have been dropped??

RDeW








.



Relevant Pages

  • Re: CoUninitialize() and CComPtr<> object lifetimes
    ... > seems that the destructor for my CComPtr<> is not being called until ... It does not help that CoInitialize() is being called ... called when the DLL is loaded, and its destructor - when the DLL is ... loaded until CoUninitialize. ...
    (microsoft.public.vc.atl)
  • Re: Windows Service & ADO problem
    ... As ADO is based on COM it needs to call coInitialize to initialize its ... Well, actually Microsoft recommends to ... if you don't call coUninitialize there is a lot of things not ... It also may be a problem with MDAC or COM corruption/bug. ...
    (borland.public.delphi.database.ado)
  • Re: Calling Coinitialize
    ... > Delphi 5 C/S compiled programs and use ADO. ... > the dll's doesn't seem to help) and then it will immediately crash ... not calling coInitialize and coUninitialize at all. ...
    (borland.public.delphi.database.ado)
  • Re: Question Error Access violation in CoUninitialize() call
    ... Success = false; ... CoInitialize may fail and if it does, ... CoUninitialize. ... If you decide you should be calling CoInitialize, ...
    (microsoft.public.win32.programmer.ole)
  • Re: Question Error Access violation in CoUninitialize() call
    ... CoInitialize may fail and if it does, ... If you decide you should be calling CoInitialize, ... fails, do not call CoUninitialize. ... released all interfaces before calling CoUninitialize. ...
    (microsoft.public.win32.programmer.ole)