The COM object created by CComObject :: CreateInstance is not destroyed when the pointer goes out of scope

Using the CComObject Smart Pointer I create a COM object by calling its static CreateInstance method. But when I leave my program, at least in VS13, this object remains on. Here is my code:

 CComObject< CMyAtlObject > * myAtlCOMObject = NULL; HRESULT hr = CComObject< CMyAtlObject >::CreateInstance(&myAtlCOMObject); ASSERT(SUCCEEDED(hr)); 

I expected the ~CComObject() method to be called when exiting a scope that is not executing.

I tried to put the code above in braces to make the newly created object go out of scope. I tried calling FinalRelease on myAtlCOMObject and was able to manually call Release on myAtlCOMObject , but the program still did not stop working in VS13.

What am I missing?

+5
source share
1 answer

Here is the code with inline comments:

 { CComObject<CMyAtlObject>* myAtlCOMObject = NULL; HRESULT hr = CComObject< CMyAtlObject >::CreateInstance(&myAtlCOMObject); ASSERT(SUCCEEDED(hr)); // NOTE: Created new object with reference count of ZERO { const CComQIPtr<IMyAtlObject> pMyAtlObject = myAtlCOMObject; // NOTE: Reference count increased to ONE } // NOTE: ~CComQIPtr went out of scope and called IUnknown::Release // decrementing counter to ZERO; decrement to zero causes destruction } // NOTE: There is no ~CComObject call here on myAtlCOMObject going out of scope // since myAtlCOMObject is a raw pointer 

What am I missing?

You are missing the following:

  • CreateInstance creates a new object and gets you a raw pointer, which is not going to destroy on its own when leaving the area
  • CreateInstance creates an object in an "unstable" state with a refcount with zero, its self-negation when managing a link starts after something increments the AT LEAST ONCE counter, and then decreases it to zero; CComQIPtr above - an example of this

MSDN on CreateInstance :

The returned object has a reference count of zero, so call AddRef immediately, then use Release to release the reference to the object pointer when you are done.

What do you use instead of CComObject::CreateInstance ?

I have a helper template class CObjectPtr that acts just like the well-known CComPtr and wraps / manipulates the native C ++ class.

My code is:

 CObjectPtr<CFoo> pFoo; pFoo.Construct(); // Instantiates automatically adding reference CFoo* pRawFoo = pFoo; // Acts as a pointer CComPtr<IFoo> pFooInterface = pFoo; // Good for exposing inmepleted interafaces CObjectPtr<CFoo> pAnotherFoo = pFoo; // Same instance proper reference counting // ~CObjectPtr releases reference, destroys the object on last release 

This answer also contains another simple wrapper: What is the best way to initialize a reference counter for a non-created COM object? .

+7
source

Source: https://habr.com/ru/post/1201570/


All Articles