C++ 通过调用IUnknown::Release()释放COM接口集合
在我的应用程序中,我需要将COM接口的发布推迟到以后。因此,我将接口指针存储在C++ 通过调用IUnknown::Release()释放COM接口集合,c++,com,com-interface,C++,Com,Com Interface,在我的应用程序中,我需要将COM接口的发布推迟到以后。因此,我将接口指针存储在std::vector COMInterfaces中,稍后我将遍历所有指针并调用Release(),如下所示: for(IUnknown* item : COMInterfaces) item->Release(); 然而,在以下第4.1.3节中,我读到: 在COM中,只有接口被引用计数,而不是对象本身。在客户机获得对特定接口的引用后,它必须准确地在该接口上调用release方法,而不是在引用同一对象的不同接口
std::vector COMInterfaces
中,稍后我将遍历所有指针并调用Release()
,如下所示:
for(IUnknown* item : COMInterfaces) item->Release();
然而,在以下第4.1.3节中,我读到:
在COM中,只有接口被引用计数,而不是对象本身。在客户机获得对特定接口的引用后,它必须准确地在该接口上调用release方法,而不是在引用同一对象的不同接口上调用release方法
所以,现在我有点困惑,是否可以以多态方式发布接口。我找不到任何文档明确说明这是否正确
编辑:
下面的评论证实了这一点,我将这样使用它。但是,欢迎任何指向官方文档的指针,以及解释为什么有时我会看到以下代码(这也是Microsoft如何定义SafeRelease()
)
你不能做的是将IUnknown*投射到其他任何东西中(你必须始终使用QueryInterface,而不是“原始”投射)。如果不这样做,就不会有任何问题。任何COM接口都是IUnknown。只要只调用
AddRef()
、Release()
和QueryInterface()
,任何向下或向上转换都应该是安全的。假设您有一个IDispatch
界面。您可以调用lpDisp->Release()
。如果调用((IUnknown*)lpDisp)->Release()
,则会得到相同的结果。我相信这一段特别指的是只能通过查询接口
(而不是向下转换)找到的接口。此时,菱形继承开始发挥作用,每个可查询接口都有自己的IUnknown
副本。这些副本可以有三种方法的不同实现,这可能是本段警告的。在旁注中,使用std::vector
会更安全,这样您就不必手动调用Release()
。这样,当向量
超出范围时,接口会自动释放,特别是在引发意外异常时。除了IUnknown*
之外,不能使用任何指针类型调用您的Release
。这与COM无关,只是基本的类型安全性。如果您可以将Dervied*p
传递给采用Base*&
的函数,则该函数可以将一些不相关的另一个派生的*
分配给p
。
template<class T>
void Release(T*& comInterface) {
if(comInterface) {
comInterface->Release();
comInterface = nullptr;
}
}
void Release(IUnknown*& comInterface) {
if(comInterface) {
comInterface->Release();
comInterface = nullptr;
}
}