I am reading a COM sample at http://msdn.microsoft.com/en-us/library/windows/desktop/dd389098(v=vs.85).aspx
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 **). What does (void **)&pControl want to return?
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
What does
(void **)&pControl
want to return?
QueryInterface()
is one of the three methods of IUnknown
, which is the base root interface of all COM interfaces.
The MSDN documentation for IUnknown::QueryInterface()
clearly states that:
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. Upon successful return, *ppvObject contains the requested interface pointer to the object. If the object does not support the interface, *ppvObject is set to 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
.
Now, let's try to better understand why the double pointer indirection: void**
.
void*
means "pointer to anything" .
So, one might think: "Why isn't the second parameter of QueryInterface()
just a 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.
And, in C (and COM has several C-isms), when you have an output parameter, you must use a pointer ( *
).
( Note In C++ you can also use a reference &
.)
So, in this case we have the first level of indirection of void*
that means "pointer to anything" .
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*').
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.