C# 使用GlobalInterfaceTable时如何调用FinalRelease?
我正在使用VisualStudio2008,我已经创建了一个ATL项目。我已经为这个项目添加了一个ATL简单对象。我想在创建对象时将对象添加到全局接口表中,因此在FinalConstruct调用中有以下代码:C# 使用GlobalInterfaceTable时如何调用FinalRelease?,c#,com,atl,C#,Com,Atl,我正在使用VisualStudio2008,我已经创建了一个ATL项目。我已经为这个项目添加了一个ATL简单对象。我想在创建对象时将对象添加到全局接口表中,因此在FinalConstruct调用中有以下代码: HRESULT res; res = CoCreateInstance(GLSID_StdGlobalInterfaceTable, NULL, CLSCTX_INPROC_SERVER, IID_IGlobalInterfaceTable, (void **)mGit); // res
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
}
然后我创建了一个C#项目,添加了DLL作为引用,并创建了一个新的SimObjClass实例。我从VC++项目调试了这个项目,看到FinalConstruct被调用了,一切都很顺利。然后我想删除COM对象,因此我调用:
int res = Marshal.ReleaseComObject(mSimObjClass); // res is 0
从我的C#应用程序。但是在调试应用程序时,我注意到FinalRelease没有被调用。进一步阅读,RegisterInterfaceingGlobal似乎将增加引用计数
我的问题是,在使用GIT时,确保调用FinalRelease的正确方法是什么?我真的不想创建一个手动执行的函数,因为这似乎违背了FinalRelease的目的。有什么想法吗
编辑:我还应该注意,如果我删除Register调用,当我调用ReleaseComObject时,FinalRelease确实会被调用。是,调用RRIG将增加引用计数。您不能使用FinalRelease,当引用计数下降到1时,您必须撤销它。在ATL中,除了从CComObjectRootBase派生以便编写自己的InternalRelease()之外,我看不到一种明显的方法来实现这一点
您最好使用发布和撤销方法来明确这一点。好的,我就是这么想的。有没有简单的方法来获取引用计数?我正在考虑把它变成一个单例,所以我不想撤销它,除非没有任何引用。也许这就是您从CComObjectRootBase派生的含义。你有这样的例子吗,或者知道我在哪里可以找到吗?从CComObjectRootBase创建一个派生类是重新实现Release()方法所需要的,这样你就可以看到引用计数下降到1。好的,谢谢,所以我正在看m_dwRef的引用计数是否正确?是的。请务必仔细查看vc\atlmfc\include\atlcom.h。您必须重新实现CComObjectRootEx。以及所有使用它的类。我认为那不现实。
int res = Marshal.ReleaseComObject(mSimObjClass); // res is 0