Regeln zum Implementieren von QueryInterface
Es gibt drei Standard Regeln für die Implementierung der IUnknown::QueryInterface-Methode für ein COM-Objekt:
- Objekte müssen eine Identität aufweisen.
- Der Satz von Schnittstellen für ein Objekt instance muss statisch sein.
- Es muss möglich sein, jede Schnittstelle für ein Objekt von jeder anderen Schnittstelle erfolgreich abzufragen.
Objekte müssen eine Identität aufweisen
Für jedes angegebene Objekt instance muss ein Aufruf von QueryInterface mit IID_IUnknown immer denselben physischen Zeigerwert zurückgeben. Dadurch können Sie QueryInterface auf zwei beliebigen Schnittstellen aufrufen und die Ergebnisse vergleichen, um zu bestimmen, ob sie auf dieselbe instance eines Objekts zeigen.
Der Satz von Schnittstellen für eine Objektinstanz muss statisch sein
Der Satz von Schnittstellen, auf die für ein Objekt über QueryInterface zugegriffen werden kann, muss statisch und nicht dynamisch sein. Insbesondere, wenn QueryInterface einmal S_OK für eine bestimmte IID zurückgibt, darf es nie E_NOINTERFACE bei nachfolgenden Aufrufen desselben Objekts zurückgeben. und wenn QueryInterface E_NOINTERFACE für eine bestimmte IID zurückgibt, dürfen nachfolgende Aufrufe für dieselbe IID für dasselbe Objekt niemals S_OK zurückgeben.
Es muss möglich sein, eine beliebige Schnittstelle für ein Objekt von einer beliebigen anderen Schnittstelle erfolgreich abzufragen.
Das heißt, unter Berücksichtigung des folgenden Codes:
IA * pA = (some function returning an IA *);
IB * pB = NULL;
HRESULT hr;
hr = pA->QueryInterface(IID_IB, &pB);
es gelten die folgenden Regeln:
Wenn Sie über einen Zeiger auf eine Schnittstelle für ein Objekt verfügen, muss ein Aufruf wie der folgende für QueryInterface für dieselbe Schnittstelle erfolgreich sein:
pA->QueryInterface(IID_IA, ...)
Wenn ein Aufruf von QueryInterface für einen zweiten Schnittstellenzeiger erfolgreich ist, muss auch ein Aufruf von QueryInterface von diesem Zeiger für die erste Schnittstelle erfolgreich sein. Wenn pB erfolgreich abgerufen wurde, muss auch Folgendes erfolgreich sein:
pB->QueryInterface(IID_IA, ...)
Jede Schnittstelle muss in der Lage sein, jede andere Schnittstelle für ein Objekt abzufragen. Wenn pB erfolgreich abgerufen wurde und Sie mit diesem Zeiger erfolgreich eine dritte Schnittstelle (IC) abfragen, müssen Sie auch in der Lage sein, den IC mithilfe des ersten Zeigers pA erfolgreich abzufragen. In diesem Fall muss die folgende Sequenz erfolgreich sein:
IC * pC = NULL; hr = pB->QueryInterface(IID_IC, &pC); pA->QueryInterface(IID_IC, ...)
Schnittstellenimplementierungen müssen einen Zähler mit ausstehenden Zeigerverweise auf alle Schnittstellen eines bestimmten Objekts beibehalten. Sie sollten eine ganze Zahl ohne Vorzeichen für den Zähler verwenden.
Wenn ein Client wissen muss, dass Ressourcen freigegeben wurden, muss er vor dem Aufrufen von IUnknown::Release eine Methode in einer Schnittstelle des Objekts mit höherer Semantik verwenden.
Zugehörige Themen