代码之家  ›  专栏  ›  技术社区  ›  SwDevMan81

当使用GlobalInterfaceTable时,如何让finalRelease被调用?

  •  0
  • SwDevMan81  · 技术社区  · 15 年前

    我正在使用Visual Studio 2008,并且创建了一个ATL项目。我为这个项目加载了一个ATL简单对象。我想在创建对象时将我的对象添加到全局接口表中,因此在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。进一步阅读,似乎RegisterInterfaceingGlobal将增加引用计数。

    我的问题是,在使用Git时,确保调用finalRelease的正确方法是什么?我真的不想创建一个手动执行的函数,因为这似乎违背了finalRelease的目的。有什么想法吗?

    编辑:我还应该注意,如果我删除register调用,finalRelease在我调用releaseComObject时会被调用。

    1 回复  |  直到 15 年前
        1
  •  0
  •   Hans Passant    15 年前

    是的,调用rrig将增加引用计数。你不能使用finalrelease,当引用计数下降到1时,你必须撤销它。除了从ccombjectrootbase派生以便编写自己的internalrelease()之外,我在ATL中看不到一种明显的方法来实现这一点。

    您最好使用发布和撤销方法来显式地说明这一点。