检查 COM 指针是否相等

4

如果我有两个COM接口指针(即ID3D11Texture2D),我想检查它们是否是同一基础类实例,我能直接比较这两个指针是否相等吗?我看过一些代码,在进行比较之前我们将其转换为其他类型,所以想确认一下。

BOOL IsEqual (ID3D11Texture2D *pTexture1, ID3D11Texture2D *pTexture2)
{
    if (pTexture1 == pTexture2)
    {
        return true;
    }
    else
    {
        return false;
    }
} 

谢谢。
1个回答

9
正确的 COM 方法是使用 IUnknown 进行接口查询。MSDN 中引用的一句话如下here
“对于任何一个对象,对该对象的任何接口进行 IUnknown 接口的特定查询必须始终返回相同的指针值。这使得客户端可以通过调用带有 IID_IUnknown 的 QueryInterface 并比较结果来确定两个指针是否指向同一组件。特别地,并非针对除 IUnknown 之外的接口(即使是通过相同指针的同一接口)进行的查询必须返回相同的指针值。”
因此,正确的代码如下:
BOOL IsEqual (ID3D11Texture2D *pTexture1, ID3D11Texture2D *pTexture2)
{
    IUnknown *u1, *u2;

    pTexture1->QueryInterface(IID_IUnknown, &u1);
    pTexture2->QueryInterface(IID_IUnknown, &u2);

    BOOL areSame = u1 == u2;
    u1->Release();
    u2->Release();

    return areSame;
}

更新

  1. 添加了一个调用Release以减少引用计数的功能。感谢好评。
  2. 您也可以使用ComPtr完成此任务。请查阅MSDN。

2
不要忘记需要在这些指针上调用 Release() - Michael Burr
我能理解为什么在指针比较之前需要进行QI,但是从实用的角度来看,我很难理解这一点。接口指针只是底层类实现的接口方法的vtbl指针。事实上,我见过的大多数QI实现都是“this”指针的简单静态转换,它只是遍历类实现的内存布局以获取vtbl指针。因此,我不禁想知道,在什么情况下,如果我们通过相同的指针QI相同的接口,我们不会返回相同的指针? - lancery
@Simon - 我现在完全理解 COM 契约了。我只是好奇,有哪些情况下我们会故意实现 QI,以使得通过相同指针对同一接口进行的 QI 不会返回相同的指针值,以及这样做的优势与另一种更直观的选择相比是什么。 - lancery
你还应该检查返回值,以查看 QI 是否成功(或将指针初始化为 null)。 - M.M
在这种情况下,另一方是Direct3D。但我也不会对Direct3D做出任何假设。 - Alex Shtof
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接