无效指针指针(void **)

时间:2014-04-15 18:48:48

标签: c++ pointers com void-pointers pointer-to-pointer

我正在http://msdn.microsoft.com/en-us/library/windows/desktop/dd389098(v=vs.85).aspx

阅读COM样本

中我真的无法理解(void **)
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);

所以我尝试了类

的不同类型的指针返回的一些值
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 << ")";
}

并打印

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

(void *)与(void **)确实没有区别。 (void **)&amp; pControl想要返回什么?

1 个答案:

答案 0 :(得分:5)

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

(void **)&pControl想要返回什么?

QueryInterface() IUnknown的三种方法之一,它是所有 COM接口的基本根接口。

MSDN documentation for IUnknown::QueryInterface()明确指出:

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

ppvObject [out]指针变量的地址,该变量接收 riid 参数中请求的接口指针。   成功返回后, * ppvObject 包含所请求的接口指针   宾语。如果对象不支持该接口,则 * ppvObject 设置为 NULL

因此,在您的特定情况下,成功返回后,pControl将包含指向IMediaControl接口的请求指针,如您在函数调用中通过第一个参数IID_IMediaControl指定的那样。 / p>


现在,让我们试着更好地理解为什么双指针间接:void**

void*表示“指向任何内容的指针”

所以,有人可能会想:“为什么QueryInterface()的第二个参数不是void*?”

问题是此参数是输出参数。这意味着QueryInterface()会将写入该参数,以便调用者使用它。

而且,在C(和COM有几个C-isms)中,当你有一个输出参数时,你必须使用指针*) 。
注意在C ++中,您还可以使用引用&。)

所以,在这种情况下,我们有void*的第一级间接,这意味着“指向任何东西的指针”
第二级间接(另一个*),表示:“这是输出参数”

你也可以这样想:

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*').