使用GlobalInterfaceTable时如何调用FinalRelease?

时间:2010-01-04 16:23:52

标签: c# com atl

我正在使用Visual Studio 2008,我创建了一个ATL项目。我已经为项目添加了一个ATL Simple Object。我想在创建对象时将我的对象添加到全局接口表,所以我在FinalConstruct调用中有以下代码:

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
}

为了清理,我在FinalRelease调用中添加了以下内容:

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

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

然后我创建了一个C#项目并添加了DLL作为参考,并创建了一个新的SimObjClass实例。我从VC ++项目调试项目,看到调用了FinalConstruct,一切都很愉快。然后我想删除COM对象,所以我打电话:

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

来自我的C#应用​​程序。但是在调试应用程序时,我注意到没有调用FinalRelease。进一步阅读,看来RegisterInterfaceInGlobal将增加引用计数。

我的问题是,在使用GIT时确保调用FinalRelease的正确方法是什么?我真的不想创建一个手动执行的功能,因为这似乎打败了FinalRelease的目的。有什么想法吗?

编辑:我还应该注意,如果我删除了Register调用,当调用ReleaseComObject时会调用FinalRelease。

1 个答案:

答案 0 :(得分:0)

是的,调用RRIG会增加引用计数。您不能使用FinalRelease,当引用计数下降到1时,您将不得不撤销它。我没有看到在ATL中执行此操作的明显方法,除了从CComObjectRootBase派生,因此您可以编写自己的InternalRelease( )。

你可能最好用一个发布和撤销方法来明确这个。