Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Tip
Moderne QueryInterface-Muster – Verwenden IID_PPV_ARGS und intelligente Zeiger. Unformatierte QueryInterface Aufrufe sind fehleranfällig (nicht übereinstimmende IID- und Zeigertypen). Moderner C++-Code sollte typsichere Hilfsprogramme verwenden:
#include <wrl/client.h> // Microsoft::WRL::ComPtr
Microsoft::WRL::ComPtr<IUnknown> unknown = /* ... */;
Microsoft::WRL::ComPtr<IPersistFile> persistFile;
// ✅ Best — ComPtr::As() handles QI + type safety + Release automatically
HRESULT hr = unknown.As(&persistFile);
// ✅ Good — IID_PPV_ARGS macro ensures IID matches the pointer type
hr = unknown->QueryInterface(IID_PPV_ARGS(&persistFile));
// ❌ Dangerous — IID and pointer type can mismatch silently
hr = unknown->QueryInterface(IID_IPersistFile, (void**)&persistFile);
C++/WinRT-Entsprechung:
#include <winrt/base.h>
winrt::com_ptr<IUnknown> unknown = /* ... */;
auto persistFile = unknown.as<IPersistFile>(); // throws on failure
auto maybePF = unknown.try_as<IPersistFile>(); // returns nullptr on failure
Wichtige Regeln: Nehmen Sie niemals eine Typumwandlung von Schnittstellenzeigern ohne QueryInterface vor — die COM-Identitätsregeln erfordern, dass jeder Schnittstellenzeiger über QI oder CoCreateInstance abgerufen wird. Direkte Umwandlungen (static_cast, reinterpret_cast) erzeugen ein nicht definiertes Verhalten.
Nachdem Sie einen anfänglichen Zeiger auf eine Schnittstelle in einem Objekt haben, verfügt COM über einen sehr einfachen Mechanismus, um herauszufinden, ob das Objekt eine andere bestimmte Schnittstelle unterstützt, und wenn ja, einen Zeiger darauf zu erhalten. (Informationen zum Abrufen eines anfänglichen Zeigers auf eine Schnittstelle in einem Objekt finden Sie unter Abrufen eines Zeigers auf ein Objekt.) Dieser Mechanismus ist die QueryInterface-Methode der IUnknown-Schnittstelle . Wenn das Objekt die angeforderte Schnittstelle unterstützt, muss die Methode einen Zeiger auf diese Schnittstelle zurückgeben. Dadurch kann ein Objekt frei durch die schnittstellen navigieren, die ein Objekt unterstützt. QueryInterface trennt die Anforderung "Unterstützen Sie einen gegebenen Vertrag?" von der leistungsstarken Nutzung dieses Vertrags, sobald die Verhandlungen erfolgreich waren.
Wenn ein Client anfänglich Zugriff auf ein Objekt erhält, empfängt dieser Client mindestens einen IUnknown-Schnittstellenzeiger (die grundlegendste Schnittstelle), über die er die Lebensdauer des Objekts steuern kann, indem er das Objekt angibt, wann es mit dem Objekt fertig ist, und QueryInterface aufrufen. Der Client ist so programmiert, dass er jedes von ihm verwaltete Objekt auffordert, bestimmte Operationen auszuführen, aber die IUnknown-Schnittstelle verfügt über keine Funktionen für diese Operationen. Stattdessen werden diese Vorgänge über andere Schnittstellen ausgedrückt. Der Client ist daher so programmiert, mit Objekten für diese Schnittstellen zu verhandeln. Insbesondere ruft der Client QueryInterface auf, um ein Objekt für eine Schnittstelle anzufordern, über die der Client die gewünschten Vorgänge aufrufen kann.
Da das Objekt QueryInterface implementiert, kann es die Anforderung annehmen oder ablehnen. Wenn das Objekt die Anforderung des Clients akzeptiert, gibt QueryInterface einen neuen Zeiger auf die angeforderte Schnittstelle an den Client zurück. Über diesen Schnittstellenzeiger hat der Client Zugriff auf die Methoden dieser Schnittstelle. Wenn das Objekt dagegen die Anforderung des Clients ablehnt, gibt QueryInterface einen NULL-Zeiger ( ein Fehler ) zurück, und der Client hat keinen Zeiger, über den die gewünschten Funktionen aufgerufen werden sollen. In diesem Fall muss der Kunde mit dieser Möglichkeit ordnungsgemäß umgehen. Angenommen, ein Client verfügt über einen Zeiger auf die Schnittstelle A eines Objekts und fragt nach Schnittstellen B und C. Angenommen, das Objekt unterstützt auch die Schnittstelle B, unterstützt aber keine Schnittstelle C. Das Ergebnis ist, dass das Objekt einen Zeiger auf B zurückgibt und meldet, dass C nicht unterstützt wird.
Ein wichtiger Punkt ist, dass es dem Client unmöglich ist, das Objekt zur Ausführung der über die angeforderte Schnittstelle definierten Vorgänge zu veranlassen, wenn ein Objekt einen Aufruf von QueryInterface ablehnt. Ein Client muss über einen Schnittstellenzeiger verfügen, um Methoden in dieser Schnittstelle aufzurufen. Wenn das Objekt sich weigert, den angeforderten Zeiger bereitzustellen, muss der Client darauf vorbereitet sein, ohne ihn auszukommen, entweder indem er darauf verzichtet, mit diesem Objekt das zu tun, was er beabsichtigt hatte, oder indem er versucht, auf eine andere, vielleicht weniger leistungsfähige Schnittstelle zurückzugreifen. Dieses Feature der COM-Funktionalität funktioniert gut im Vergleich zu anderen objektorientierten Systemen, in denen Sie nicht wissen können, ob eine Funktion funktioniert, bis Sie diese Funktion aufrufen, und selbst dann ist die Behandlung von Fehlern unsicher. QueryInterface bietet eine zuverlässige und konsistente Möglichkeit, zu wissen, ob ein Objekt eine Schnittstelle unterstützt, bevor versucht wird, seine Methoden aufzurufen.
Die QueryInterface-Methode bietet auch eine robuste und zuverlässige Möglichkeit für ein Objekt, um anzugeben, dass ein bestimmter Vertrag nicht unterstützt wird. Das heißt, wenn man in einem Aufruf von QueryInterface ein "altes" Objekt fragt, ob es eine "neue" Schnittstelle unterstützt (z. B. eine, die erfunden wurde, nachdem das alte Objekt ausgeliefert wurde), wird das alte Objekt zuverlässig, ohne einen Absturz zu verursachen, "nein" antworten. Die Technologie, die dies unterstützt, ist der Algorithmus, mit dem IIDs zugeordnet werden. Obwohl dies wie ein kleiner Punkt aussieht, ist es für die allgemeine Architektur des Systems äußerst wichtig, und die Fähigkeit, legacy-Elemente über neue Funktionen zu erfragen, ist überraschenderweise ein Feature, das in den meisten anderen Objektarchitekturen nicht vorhanden ist.
Zugehörige Themen