Указатель недействительного указателя (void **)

Я читаю образец COM в http://msdn.microsoft.com/en-us/library/windows/desktop/dd389098(v=vs.85).aspx

Я действительно не могу понять (недействительно **) в

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 **). Что делает (недействительным **)&pControl хотите вернуть?

4

Решение

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

Что значит (void **)&pControl хотите вернуться?

QueryInterface() является одним из трех методов IUnknown, который является базовым корневым интерфейсом все COM интерфейсы.

Документация MSDN для IUnknown::QueryInterface() четко говорится, что:

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

ppvObject [out] Адрес переменной указателя, которая получает указатель интерфейса, запрошенный в riid параметр.
После успешного возвращения, * ppvObject содержит запрошенный указатель на интерфейс
объект. Если объект не поддерживает интерфейс, * ppvObject установлен в НОЛЬ.

Итак, в вашем конкретном случае, после успешного возвращения, 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*').
4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]