简体   繁体   English

无效指针指针(void **)

[英]Void pointer pointer (void **)

I am reading a COM sample at http://msdn.microsoft.com/en-us/library/windows/desktop/dd389098(v=vs.85).aspx 我正在http://msdn.microsoft.com/en-us/library/windows/desktop/dd389098(v=vs.85).aspx上阅读COM示例。

I really cannot comprehend (void **) in 我真的无法理解(无效**)

hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);

So I have tried some values returned by different types of pointers by the class 所以我尝试了类不同类型的指针返回的一些值

class Point{
private:
    int x, y;
public:
    Point(int inputX, int inputY){x = inputX, y = inputY;}
    int getX(){return x;}
    int getY(){return y;}
    friend ostream& operator << (ostream &out, Point &cPoint);
    Point operator-(){
        return Point(-x, -y);
    }
};

ostream& operator << (ostream &out, Point &cPoint){
    return out<< "(" << cPoint.x << ", " << cPoint.y << ")";
}

and printing out 并打印出来

Point *p = new Point(1,2);
cout << p << endl << &p << endl << endl
<< *&p << endl<< **&p << endl<<endl 
<< (void *) &p << endl << (void **) &p ;

(void*) really has no difference with (void **). (void *)与(void **)真的没什么区别。 What does (void **)&pControl want to return? (void **)&pControl想要返回什么?

 hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl); 

What does (void **)&pControl want to return? (void **)&pControl想要返回什么?

QueryInterface() is one of the three methods of IUnknown , which is the base root interface of all COM interfaces. QueryInterface()IUnknown的三种方法之一,它是所有 COM接口的基本根接口。

The MSDN documentation for IUnknown::QueryInterface() clearly states that: IUnknown::QueryInterface()MSDN文档明确指出:

 HRESULT QueryInterface( [in] REFIID riid, [out] void **ppvObject ); 

ppvObject [out] The address of a pointer variable that receives the interface pointer requested in the riid parameter. ppvObject [out]接收riid参数中请求的接口指针的指针变量的地址。 Upon successful return, *ppvObject contains the requested interface pointer to the object. 成功返回后, * ppvObject包含指向对象的请求接口指针。 If the object does not support the interface, *ppvObject is set to NULL . 如果对象不支持该接口,则* ppvObject设置为NULL

So, in your particular case, upon successful return, pControl will contain the requested pointer to the IMediaControl interface, as specified in your function call via the first argument IID_IMediaControl . 因此,在您的特定情况下,成功返回后, pControl将包含所请求的指向IMediaControl接口的指针,如您在函数调用中通过第一个参数IID_IMediaControl指定的IID_IMediaControl


Now, let's try to better understand why the double pointer indirection: void** . 现在,让我们试着更好地理解为什么双指针间接: void**

void* means "pointer to anything" . void*表示“指向任何东西的指针”

So, one might think: "Why isn't the second parameter of QueryInterface() just a void* ?" 所以,有人可能会想: “为什么QueryInterface()的第二个参数不是一个void* ?”

The problem is that this parameter is an output parameter. 问题是此参数是输出参数。 This means that QueryInterface() will write something into that parameter, for the caller to use it. 这意味着QueryInterface()该参数中写入一些内容,以便调用者使用它。

And, in C (and COM has several C-isms), when you have an output parameter, you must use a pointer ( * ). 而且,在C(和COM有几个C-isms)中,当你有一个输出参数时,你必须使用指针* )。
( Note In C++ you can also use a reference & .) 注意在C ++中,您也可以使用引用& 。)

So, in this case we have the first level of indirection of void* that means "pointer to anything" . 因此,在这种情况下,我们有void*的第一级间接,这意味着“指向任何东西的指针”
And the second level of indirection (the other * ), that means: "This is an output parameter" . 而第二级间接(另一个* ),意味着: “这是一个输出参数”

You can think of it also in this way: 您也可以这样想到它:

typedef void* PointerToAnything;

HRESULT QueryInterface(..., /* [out] */ PointerToAnything* pSomeInterface);

// pSomeInterface is an output parameter.
//
// [out] --> use * (pointer), 
// so it's 'PointerToAnything*' (not just 'PointerToAnything'),
// so, with proper substitution, it's 'void**' (not just 'void*').

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM