【问题标题】:Check COM pointers for equality检查 COM 指针是否相等
【发布时间】:2014-06-17 16:47:51
【问题描述】:

如果我有两个 COM 接口指针(即 ID3D11Texture2D),并且我想检查它们是否是相同的底层类实例,我可以直接比较这两个指针是否相等?我已经看到在比较完成之前我们将其转换为其他内容的代码,所以想确认一下。

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

谢谢。

【问题讨论】:

    标签: c++ com


    【解决方案1】:

    执行此操作的正确 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 的调用,以减少引用计数。感谢优秀的 cmets。
    2. 您也可以将 ComPtr 用于此作业。请查看 MSDN。

    【讨论】:

    • 不要忘记Release() 需要在这些指针上调用。
    • 我可以看到为什么需要在指针比较之前进行 IUKnown 的 QI。但是,我很难从实用的角度理解这一点。接口指针只是底层类实现的接口方法的 vtbl 指针。事实上,我见过的大多数 QI 的实现都是简单的“this”指针的 static_casts,它只是简单地遍历类实现的内存布局以获取 vtbl 指针。因此,我不禁想知道,如果我们通过同一个指针对同一个接口进行 QI,在什么情况下我们不会返回同一个指针?
    • @lancery - COM 身份仅在 IUnknown 上。您不能为其他 IID 假设任何内容,尽管某些实现确实在幕后返回相同的指针。还要检查这个:msdn.microsoft.com/en-us/library/windows/desktop/…
    • @Simon - 我现在完全得到了 COM 合同。我只是好奇在哪些情况下我们将有目的地实现 QI,以便通过相同指针的相同接口的 QI 不会返回相同的指针值,与替代方案相比,这样做的优势是什么,这似乎更多直观。
    • 您还应该检查返回值以查看 QI 是否成功(或将指针初始化为 null)。
    猜你喜欢
    • 2012-06-10
    • 2020-08-30
    • 2018-11-16
    • 2011-06-07
    • 2020-03-29
    • 2015-08-26
    • 2021-07-16
    • 2022-11-01
    相关资源
    最近更新 更多