tags:

views:

229

answers:

1

I am using Visual Studio 2008 and I have created an ATL Project. I have aded a ATL Simple Object to the project. I want to add my object to the Global Interface Table when the object is created, so I have the following code in my FinalConstruct call:

HRESULT res;
res = CoCreateInstance(GLSID_StdGlobalInterfaceTable, NULL, CLSCTX_INPROC_SERVER, IID_IGlobalInterfaceTable, (void **)mGit);
// res here is OK, mGit is not null
if(mGit != NULL)
{
   CComQIPtr<ISimObj> com_ptr = this;
   result = mGit->RegisterInterfaceInGlobal(com_ptr, __uuidof(ISimObj), &mGitCookie);
   // result is OK and mGitCookie is not null
}

To clean up, I added the following to the FinalRelease call:

if((mGit != NULL) && (mGitCookie != NULL))
{
   result = mGit->RevokeInterfaceFromGlobal(mGitCookie);
}

if(mGit != NULL)
{
   mGit->Release();
}

Then I created a C# Project and added the DLL as a reference and created a new Instance of SimObjClass. I debug the project from the VC++ project and see that FinalConstruct is called and everything is happy. Then I want to delete the COM object so I call:

int res = Marshal.ReleaseComObject(mSimObjClass); // res is 0

from my C# application. But while debugging the application, I noticed that FinalRelease is not called. Reading further, it appears that RegisterInterfaceInGlobal will increment the reference count.

My question is, what is the correct way to ensure that FinalRelease is called when using GIT? I dont really want to create a function that will do it manually, since that seems to defeat the purpose of FinalRelease. Any ideas?

EDIT: I should also note, that if I remove the Register call, FinalRelease does get called when I call ReleaseComObject.

A: 

Yes, calling RRIG will increment the reference count. You can't use FinalRelease, you'll have to revoke it when the reference count drops down to 1. I don't see an obvious way to do this in ATL, other than deriving from CComObjectRootBase so you can write your own InternalRelease().

You might be better off making this explicit with, say, a Publish and Revoke method.

Hans Passant
Ok, thats what I figured. Is there a simple way to get the reference count? I'm thinking about making it a Singleton, so I dont want to Revoke unless there arent any references to it. Maybe this is what you are hinting at by deriving from CComObjectRootBase. Do you have any example of this or know where I could find one?
SwDevMan81
Creating a derived class from CComObjectRootBase is what it takes to re-implement the Release() method so you can see the reference count dropping to 1.
Hans Passant
Ok thanks, so I'm looking at m_dwRef for the reference count correct?
SwDevMan81
Yes. Be sure to take a good look at vc\atlmfc\include\atlcom.h. You'll have to re-implement CComObjectRootEx. And all the classes that use it. I don't think that's practical.
Hans Passant