我正在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想要返回什么?
答案 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*').