QueryInterface()可以为我们提供nullptr时成功? [英] Could QueryInterface() provide us with nullptr when succeed?

查看:466
本文介绍了QueryInterface()可以为我们提供nullptr时成功?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想象一下情况:

CComPtr<IGraphBuilder> pGraph;
HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pGraph));
if (SUCCEEDED(hr))
{
    CComPtr<IMediaControl> pControl;
    hr = pGraph->QueryInterface(IID_PPV_ARGS(&pControl));
    if(SUCCEEDED(hr))
    {...}
}


$ b b

我想知道,如果 pControl 可以在最后一个块 {...} 内使用nullptr。发生这个问题,因为我看到了代码:

I wonder, if pControl could ever be nullptr inside last block {...}. The question occurred, because I saw that code:

if(SUCCEEDED(hr) && pControl)
{...}

我认为& pControl 作为冗余。是对吗?

I consider that part && pControl as a redundant one. Am I right?

推荐答案

QueryInterface() 在失败时提供成功时有效的(所以非空)接口指针和空指针。但是你不知道一些具体的实现是否遵循这个规则,你引用的代码最有可能尝试防御。

QueryInterface() is required to provide a valid (so non-null) interface pointer on success and a null pointer on failure. However you don't know whether some specific implementation follows that rule and the code you cite most likely tries to be defensive.

那么,下面的

HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL,
    CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pGraph));

也会调用 QueryInterface()以检索指向所请求接口的指针。如果代码想要防御,它应该检查 pGraph 在成功时是否为非空。

also calls QueryInterface() under the hood to retrieve the pointer to the requested interface. If the code wants to be defensive it should check that pGraph is non-null on success too.

这里是你不知道它是多么糟糕,当你得到 S_OK 和一个空指针。假设 QueryInterface()的工作方式如下( 真的很糟糕的代码如下,不适用于任何地方 ):

The problem here is you don't know how bad it is when you get S_OK and a null pointer. Suppose QueryInterface() works like this (really bad code follows, not for use anywhere):

HRESULT TheClass::QueryInterface( REFIID iid, void** ppv )
{
    if( iid == SomeSpecificIID ) {
        AddRef();
        *ppv = 0; //BAD IDEA, BAD CODE, JUST DON'T
        return S_OK;
    } else {
       //whatever
    }
}

伟大的防御性代码将避免解除引用这里检索的空指针和 S_OK 返回,但是引用计数将不正确 - 没有人将有机会调用匹配 Release()。所以你实例化这样一个对象,然后调用 QueryInterface()它的工作原理如上,refcount现在是2,然后你 Release()对象一次,它泄漏。

great, the defensive code will avoid dereferencing a null pointer retrieved here together with S_OK returned but reference count will be incorrect - noone will have a chance to call matching Release(). So you instantiate such an object, then call QueryInterface() which works as above, the refcount is now 2, then you Release() the object once and it leaks. How bad it happens to turn out depends on a lot of factors.

相同CoCreateInstance() - 它调用下面的 QueryInterface()这两个都可能被打破,你的里程可能有变化,无论是否检查检索的指针对空。

Same with CoCreateInstance() - it calls the same QueryInterface() under the hood. Both may be broken and your mileage may vary both with and without checking the retrieved pointer against null.

这篇关于QueryInterface()可以为我们提供nullptr时成功?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆