我们有一些使用COM的遗留软件代码。我注意到,在一个地方,我们在IInspectable指针上执行queryInterface,但不调用release。
对于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
}我将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()的正确位置/方式吗?我是否需要在适当的地方添加其他安全检查?
发布于 2018-09-25 15:13:34
在第一个foo函数中,您不应该调用myInterface->Release()。每个对Release的调用都应该与一个引用的添加配对。在该函数中,您没有执行myInterface->AddRef,所以如果您添加myInterface->Release,那么您的函数会将引用计数减1,这似乎不是正确的行为。
从概念上讲,应该在函数进入时调用AddRef,在函数退出时调用Release。尽管引用计数在COM中是“侵入性的”,但建议的编码风格是将每个接口指针视为具有其自己的引用计数。
这通常被包装在智能指针类中。但是,当使用接收原始" in“接口指针的函数时,只需省略函数中的这两个调用,并将指针视为观察者指针,就可以对添加和释放进行”优化“。
对QueryInterface的调用将隐式地执行pObj->AddRef(),但这与myInterface无关。当您完成pObj时,应该会发生一个pObj->Release() --但这是由ComPtr包装器管理的,您不应该添加显式调用。
https://stackoverflow.com/questions/52492384
复制相似问题