Tri*_*ung 4 c++ com pointers void-pointers pointer-to-pointer
我正在http://msdn.microsoft.com/zh-cn/library/windows/desktop/dd389098(v=vs.85).aspx上阅读COM示例。
我真的无法理解(void **)
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
Run Code Online (Sandbox Code Playgroud)
所以我尝试了由类的不同类型的指针返回的一些值
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 << ")";
}
Run Code Online (Sandbox Code Playgroud)
然后打印出来
Point *p = new Point(1,2);
cout << p << endl << &p << endl << endl
<< *&p << endl<< **&p << endl<<endl
<< (void *) &p << endl << (void **) &p ;
Run Code Online (Sandbox Code Playgroud)
(void *)与(void **)确实没有区别。(void **)&pControl要返回什么?
Run Code Online (Sandbox Code Playgroud)hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);什么是
(void **)&pControl想返回?
QueryInterface()是的三种方法之一IUnknown,它是所有 COM接口的基本根接口。
在为MSDN文档IUnknown::QueryInterface()中明确指出:
Run Code Online (Sandbox Code Playgroud)HRESULT QueryInterface( [in] REFIID riid, [out] void **ppvObject );ppvObject [out]指针变量的地址,该变量接收riid参数中请求的接口指针。成功返回后,* ppvObject包含所请求的指向对象的接口指针。如果对象不支持该接口,则将* ppvObject设置为NULL。
因此,在特定情况下,成功返回后,pControl将包含请求的指向IMediaControl接口的指针,如通过第一个参数在函数调用中指定的那样IID_IMediaControl。
现在,让我们尝试更好地理解为什么使用双指针间接寻址:void**。
void*表示“指向任何东西的指针”。
因此,人们可能会想:“为什么不QueryInterface()只是一个第二个参数void*?”
问题在于此参数是输出参数。这意味着QueryInterface()将在该参数中写入一些内容,以供调用者使用。
并且,在C语言中(COM具有多种C语言),当您具有输出参数时,必须使用指针(*)。
(请注意,在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*').
Run Code Online (Sandbox Code Playgroud)