Sdílet prostřednictvím


QueryInterface: Navigace v objektu

Jakmile budete mít počáteční ukazatel na rozhraní objektu, com má velmi jednoduchý mechanismus zjistit, zda objekt podporuje jiné specifické rozhraní, a pokud ano, získat ukazatel na něj. (Informace o získání počátečního ukazatele na rozhraní objektu naleznete v tématu Získání ukazatele na objekt.) Tento mechanismus je metoda QueryInterface rozhraní IUnknown. Pokud objekt podporuje požadované rozhraní, musí metoda vrátit ukazatel na toto rozhraní. To umožňuje objektu volně procházet rozhraní, která objekt podporuje. QueryInterface odděluje požadavek "Podporujete danou smlouvu?" od vysoce výkonného využití této smlouvy, jakmile budou jednání úspěšná.

Když klient zpočátku získá přístup k objektu, obdrží klient minimálně IUnknown ukazatel rozhraní (nejzákladnější rozhraní), prostřednictvím kterého může řídit životnost objektu – informováním objektu, kdy dokončí jeho použití – a vyvolá QueryInterface. Klient je naprogramovaný tak, aby požádal o provedení některých operací každý objekt, který spravuje, ale rozhraní IUnknown nemá pro tyto operace žádné funkce. Místo toho se tyto operace vyjadřují prostřednictvím jiných rozhraní. Klient je tedy naprogramován tak, aby vyjednal s objekty pro tato rozhraní. Konkrétně klient zavolá QueryInterface požádat objekt pro rozhraní, prostřednictvím kterého může klient vyvolat požadované operace.

Vzhledem k tomu, že objekt implementuje QueryInterface, má možnost přijmout nebo odmítnout požadavek. Pokud objekt přijme požadavek klienta, QueryInterface vrátí nový ukazatel na požadované rozhraní klienta. Prostřednictvím tohoto ukazatele rozhraní má klient přístup k metodám tohoto rozhraní. Pokud na druhou stranu objekt odmítne požadavek klienta, QueryInterface vrátí nulový ukazatel – chybu – a klient nemá ukazatel, přes který se mají volat požadované funkce. V takovém případě se klient musí s touto možností řádně vypořádat. Předpokládejme například, že klient má ukazatel na rozhraní A objektu a žádá o rozhraní B a C. Předpokládejme také, že objekt podporuje rozhraní B, ale nepodporuje rozhraní C. Výsledkem je, že objekt vrátí ukazatel na B a oznamuje, že rozhraní C není podporováno.

Klíčovým bodem je to, že když objekt odmítne volání QueryInterface, není možné, aby klient požádal objekt o provedení operací vyjádřených prostřednictvím požadovaného rozhraní. Klient musí mít ukazatel rozhraní pro vyvolání metod v daném rozhraní. Pokud objekt odmítne poskytnout požadovaný ukazatel, musí být klient připraven obejít se bez něj, buď tím, že upustí od zamýšlené činnosti s tímto objektem, nebo tím, že se pokusí použít jiné, možná méně výkonné rozhraní. Tato funkce modelu COM funguje dobře ve srovnání s jinými objektově orientovanými systémy, ve kterých nemůžete zjistit, zda bude nějaká funkce fungovat, dokud ji nezavoláte, a i poté je zpracování selhání nejisté. QueryInterface poskytuje spolehlivý a konzistentní způsob, jak zjistit, zda objekt podporuje rozhraní před pokusem o volání jeho metod.

Metoda QueryInterface také poskytuje robustní a spolehlivý způsob, jak objekt indikovat, že daný kontrakt nepodporuje. To znamená, že pokud se při volání QueryInterface zeptáte "starého" objektu, zda podporuje "nové" rozhraní (například takové, které bylo vynalezeno po vydání starého objektu), starý objekt spolehlivě odpoví "ne", aniž by došlo k pádu systému. Technologie, která to umožňuje, je algoritmus, podle kterého jsou přidělovány identifikátory IID. I když se to může zdát jako nevýznamná maličkost, je to velmi důležité pro celkovou architekturu systému a schopnost dotazovat se starších prvků na nové funkce je překvapivě vlastnost, která není přítomna ve většině ostatních objektových architektur.

Použití a Implementace IUnknown