Udostępnij przez


Reguły implementowania elementu QueryInterface

Istnieją trzy główne reguły, które określają implementację metody IUnknown::QueryInterface na obiekcie COM:

  • Obiekty muszą mieć tożsamość.
  • Zestaw interfejsów w wystąpieniu obiektu musi być statyczny.
  • Musi być możliwe pomyślne wykonywanie zapytań dotyczących dowolnego interfejsu w obiekcie z dowolnego innego interfejsu.

Obiekty muszą mieć tożsamość

W przypadku dowolnego wystąpienia obiektu wywołanie QueryInterface z IID_IUnknown musi zawsze zwracać tę samą wartość wskaźnika fizycznego. Pozwala to wywołać QueryInterface na dowolnych dwóch interfejsach i porównać wyniki, aby określić, czy wskazują one to samo wystąpienie obiektu.

Zestaw interfejsów w wystąpieniu obiektu musi być statyczny

Zestaw interfejsów dostępnych dla obiektu za pośrednictwem QueryInterface musi być statyczny, a nie dynamiczny. W szczególności jeśli QueryInterface zwraca S_OK dla danego identyfikatora IID raz, nigdy nie musi zwracać E_NOINTERFACE przy kolejnych wywołaniach tego samego obiektu; a jeśli QueryInterface zwraca E_NOINTERFACE dla danego identyfikatora IID, kolejne wywołania tego samego identyfikatora IID w tym samym obiekcie nigdy nie muszą zwracać S_OK.

Musi być możliwe pomyślne wykonywanie zapytań dotyczących dowolnego interfejsu w obiekcie z dowolnego innego interfejsu

Oznacza to, że biorąc pod uwagę następujący kod:

IA * pA = (some function returning an IA *); 
IB * pB = NULL; 
HRESULT   hr; 
hr = pA->QueryInterface(IID_IB, &pB); 
 

obowiązują następujące reguły:

  • Jeśli masz wskaźnik do interfejsu w obiekcie, wywołanie podobne do następującego, aby QueryInterface dla tego samego interfejsu, musi zakończyć się pomyślnie:

    pA->QueryInterface(IID_IA, ...) 
    
    
  • Jeśli wywołanie QueryInterface dla drugiego wskaźnika interfejsu powiedzie się, wywołanie QueryInterface z tego wskaźnika dla pierwszego interfejsu również musi zakończyć się pomyślnie. Jeśli punkt pB został pomyślnie uzyskany, następujące czynności również muszą się powieść:

    pB->QueryInterface(IID_IA, ...) 
    
    
  • Każdy interfejs musi mieć możliwość wykonywania zapytań dotyczących dowolnego innego interfejsu w obiekcie. Jeśli pB został pomyślnie uzyskany i pomyślnie wykonasz zapytanie dotyczące trzeciego interfejsu (IC) przy użyciu tego wskaźnika, musisz również mieć możliwość pomyślnego wykonania zapytania dotyczącego IC przy użyciu pierwszego wskaźnika pA. W takim przypadku następująca sekwencja musi zakończyć się pomyślnie:

    IC * pC = NULL; 
    hr = pB->QueryInterface(IID_IC, &pC); 
    pA->QueryInterface(IID_IC, ...) 
    
    

Implementacje interfejsu muszą obsługiwać licznik wybitnych odwołań wskaźnika do wszystkich interfejsów w danym obiekcie. Dla licznika należy użyć niepodpisanej liczby całkowitej.

Jeśli klient musi wiedzieć, że zasoby zostały zwolnione, musi użyć metody w interfejsie w obiekcie z semantyki wyższego poziomu przed wywołaniem IUnknown::Release.

używanie i implementowanie IUnknown