简体   繁体   English

释放COM接口的正确方法

[英]Correct way to release a COM interface

We have some legacy software code, which uses COM. 我们有一些旧的软件代码,它们使用COM。 I've noticed that at one place, we perform a queryInterface on an IInspectable pointer, but dont bother calling release. 我注意到,在某个地方,我们对IInspectable指针执行了queryInterface,但是不必费心调用release。

For ex: 例如:

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
}

I added Release to the above code like below : 我将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;

But I see that the above code crashes at times in the above function during release. 但是我看到上面的代码有时在发布期间在上面的函数中崩溃。 Is there something wrong in the way I'm releasing the interface ? 我发布界面的方式有问题吗? I can confirm that myInterface is not being used anywhere else in the function after the Release statement. 在Release语句之后,我可以确认在函数的其他任何地方都没有使用myInterface。

Apologies for not being able to copy/paste the actual code, but the above code summarizes pretty much the suspect code that I'm debugging. 抱歉无法复制/粘贴实际代码,但是上面的代码概括了我正在调试的可疑代码。 Basically what I want to know is, in the above scenario, do I need to call Release() ? 基本上,我想知道的是,在上述情况下,我需要调用Release()吗? And is this is the right place/way to call Release() ? 这是调用Release()的正确地方/方法吗? Do I need to add any other safety checks in place ? 我是否需要添加其他任何安全检查?

In the first foo function you should NOT call myInterface->Release() . 在第一个foo函数中,您不应调用myInterface->Release() Every call to Release should be paired with an adding of a reference. 每次对Release调用都应与引用添加在一起。 In that function you don't do myInterface->AddRef , so if you add myInterface->Release then your function will decrement the reference count by one, which does not seem like correct behaviour. 在该函数中,您无需执行myInterface->AddRef ,因此,如果添加myInterface->Release则您的函数会将引用计数减一,这似乎不正确。

Conceptually, you should call AddRef on entry to the function and Release on exit of the function. 从概念上讲,应该在函数入口处调用AddRef ,在函数出口处调用Release Even though the reference count is "intrusive" in COM, the recommended coding style is to treat each interface pointer like it has its own reference count. 即使引用计数在COM中是“侵入式”的,建议的编码样式也应将每个接口指针都视为具有其自己的引用计数。

This is normally wrapped up in smart pointer classes. 通常将其包装在智能指针类中。 But when working with a function that receives a raw "in" interface pointer, this Add and Release can be "optimized" by just omitting both of those calls in the function, and treating the pointer like an observer pointer. 但是,当使用接收到原始“输入”接口指针的函数时,只需忽略函数中的这两个调用,并将该指针视为观察者指针,即可“优化”添加和释放。


The call to QueryInterface will implicitly do pObj->AddRef() but this is nothing to do with myInterface . QueryInterface的调用将隐式执行pObj->AddRef()但这与myInterface When you are finished with pObj a pObj->Release() should occur -- but this is managed by the ComPtr wrapper, you shouldn't add an explicit call. 当您使用完pObj一个pObj->Release()应该发生-但这是由管理ComPtr包装,你不应该添加一个显式调用。

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

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