繁体   English   中英

释放COM接口的正确方法

[英]Correct way to release a COM interface

我们有一些旧的软件代码,它们使用COM。 我注意到,在某个地方,我们对IInspectable指针执行了queryInterface,但是不必费心调用release。

例如:

void foo(IInspectable* myInterface)
{
    ComPtr<OBJTYPE> pObj;
    auto hr = myInterface->QueryInterface(__uuidof(SomeType),&pObj);
    if (hr != S_OK)
    {
        return hr;
    }
    //some code that uses pObj
}

我将Release添加到上面的代码中,如下所示:

auto hr = myInterface->QueryInterface(__uuidof(SomeType),&pObj);
if (hr != S_OK)
{
    return hr;
}
myInterface->Release(); //<-- Is this the correct way to release ?
//some code that uses pObj;

但是我看到上面的代码有时在发布期间在上面的函数中崩溃。 我发布界面的方式有问题吗? 在Release语句之后,我可以确认在函数的其他任何地方都没有使用myInterface。

抱歉无法复制/粘贴实际代码,但是上面的代码概括了我正在调试的可疑代码。 基本上,我想知道的是,在上述情况下,我需要调用Release()吗? 这是调用Release()的正确地方/方法吗? 我是否需要添加其他任何安全检查?

在第一个foo函数中,您不应调用myInterface->Release() 每次对Release调用都应与引用添加在一起。 在该函数中,您无需执行myInterface->AddRef ,因此,如果添加myInterface->Release则您的函数会将引用计数减一,这似乎不正确。

从概念上讲,应该在函数入口处调用AddRef ,在函数出口处调用Release 即使引用计数在COM中是“侵入式”的,建议的编码样式也应将每个接口指针都视为具有其自己的引用计数。

通常将其包装在智能指针类中。 但是,当使用接收到原始“输入”接口指针的函数时,只需忽略函数中的这两个调用,并将该指针视为观察者指针,即可“优化”添加和释放。


QueryInterface的调用将隐式执行pObj->AddRef()但这与myInterface 当您使用完pObj一个pObj->Release()应该发生-但这是由管理ComPtr包装,你不应该添加一个显式调用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM