Void pointer pointer (void **)
c++, com, pointer-to-pointer, pointers, void-pointers
Solution
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*').
Problem
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?