Sdílet prostřednictvím


Vytvoření objektu v modelu COM

Po inicializaci knihovny COM vlákno může bezpečně používat rozhraní COM. Chcete-li použít rozhraní COM, program nejprve vytvoří instanci objektu, který toto rozhraní implementuje.

Obecně platí, že existují dva způsoby vytvoření objektu COM:

  • Modul, který implementuje objekt, může poskytnout funkci určenou speciálně k vytvoření instancí tohoto objektu.
  • Com také poskytuje obecnou funkci vytváření s názvem CoCreateInstance.

Vezměte například hypotetický Shape objekt z tématu Co je rozhraní COM?. V tomto příkladu Shape objekt implementuje rozhraní s názvem IDrawable. Grafická knihovna, která implementuje objekt Shape, může exportovat funkci s následujícím podpisem.

// Not an actual Windows function. 

HRESULT CreateShape(IDrawable** ppShape);

Vzhledem k této funkci byste mohli vytvořit nový objekt Shape následujícím způsobem.

IDrawable *pShape;

HRESULT hr = CreateShape(&pShape);
if (SUCCEEDED(hr))
{
    // Use the Shape object.
}
else
{
    // An error occurred.
}

Parametr ppShape je typu pointer-to-IDrawable. Pokud jste tento vzor ještě neviděli, může být dvojitá nepřímá řešení matoucí.

Zvažte požadavky funkce CreateShape. Funkce musí vrátit zpět volajícímu ukazatel IDrawable. Návratová hodnota funkce se ale už používá pro kód chyby nebo úspěchu. Proto musí být ukazatel vrácen prostřednictvím argumentu funkce. Volající předá funkci proměnnou typu IDrawable* a funkce tuto proměnnou přepíše novým ukazatelem IDrawable. V jazyce C++ existují pouze dva způsoby, jak funkce přepsat hodnotu parametru: předat odkazem nebo předat adresu. Com používá druhou předávací adresu. Adresa ukazatele je ukazatel na ukazatel, takže typ parametru musí být IDrawable**.

Tady je diagram, který vám pomůže vizualizovat, co se děje.

diagram ukazující s dvojitou nepřímostí ukazatele

Funkce CreateShape používá adresu pShape (&pShape) k zápisu nové hodnoty ukazatele na pShape.

CoCreateInstance: Obecný způsob vytváření objektů

Funkce CoCreateInstance poskytuje obecný mechanismus pro vytváření objektů. Chcete-li pochopit CoCreateInstance, mějte na paměti, že dva objekty COM mohou implementovat stejné rozhraní a jeden objekt může implementovat dvě nebo více rozhraní. Proto obecná funkce, která vytváří objekty, potřebuje dva údaje.

  • Který objekt se má vytvořit.
  • Jaké rozhraní získat z objektu?

Jak ale tyto informace označujeme při volání funkce? V modelu COM je objekt nebo rozhraní identifikováno přiřazením 128bitového čísla, kterému se říká globálně jedinečný identifikátor (GUID). Identifikátory GUID se generují způsobem, který je efektivně jedinečný. Identifikátory GUID představují řešení problému vytváření jedinečných identifikátorů bez centrální registrační autority. Identifikátory GUID se někdy označují jako univerzální jedinečné identifikátory (UUID). Před COM se používaly v prostředí DCE/RPC (Distributed Computing Environment/Remote Procedure Call). Pro vytváření nových identifikátorů GUID existuje několik algoritmů. Ne všechny tyto algoritmy striktně zaručují jedinečnost, ale pravděpodobnost náhodného vytvoření stejné hodnoty GUID dvakrát je extrémně malá – efektivně nula. Identifikátory GUID lze použít k identifikaci jakéhokoli druhu entity, nejen objektů a rozhraní. To je však jediné použití, které nás v tomto modulu zajímá.

Knihovna Shapes může například deklarovat dvě konstanty GUID:

extern const GUID CLSID_Shape;
extern const GUID IID_IDrawable; 

(Můžete předpokládat, že skutečné 128bitové číselné hodnoty pro tyto konstanty jsou definovány jinde.) Konstantní CLSID_Shape identifikuje Shape objekt, zatímco konstantní IID_IDrawable identifikuje IDrawable rozhraní. Předpona CLSID je zkratka pro identifikátor třídy a předpona IID je zkratka identifikátor rozhraní. Jedná se o standardní konvence vytváření názvů v modelu COM.

Vzhledem k těmto hodnotám byste vytvořili novou instanci Shape následujícím způsobem:

IDrawable *pShape;
hr = CoCreateInstance(CLSID_Shape, NULL, CLSCTX_INPROC_SERVER, IID_IDrawable,
     reinterpret_cast<void**>(&pShape));

if (SUCCEEDED(hr))
{
    // Use the Shape object.
}
else
{
    // An error occurred.
}

Funkce CoCreateInstance má pět parametrů. První a čtvrtý parametr jsou identifikátor třídy a identifikátor rozhraní. Tyto parametry v podstatě říkají funkci"Create the Shape object, and give me a pointer to the IDrawable interface" (Vytvořit objekt Shape) a dejte mi ukazatel na rozhraní IDrawable.

Nastavte druhý parametr na NULL. (Další informace o významu tohoto parametru najdete v tématu Agregační v dokumentaci com.) Třetí parametr přebírá sadu příznaků, jejichž hlavním účelem je zadat kontext spuštění objektu. Kontext spuštění určuje, zda objekt běží ve stejném procesu jako aplikace; v jiném procesu na stejném počítači; nebo na vzdáleném počítači. Následující tabulka uvádí nejběžnější hodnoty pro tento parametr.

Vlajka Popis
CLSCTX_INPROC_SERVER Stejný proces.
CLSCTX_LOCAL_SERVER Jiný proces, stejný počítač.
CLSCTX_REMOTE_SERVER Jiný počítač.
CLSCTX_ALL Použijte nejúčinnější možnost, kterou objekt podporuje. (Pořadí, od nejúčinnějších po nejméně efektivní, je: v procesu, mimo proces a mezi počítači.)

 

Dokumentace ke konkrétní komponentě vám může říct, který kontext spuštění objekt podporuje. Pokud ne, použijte CLSCTX_ALL. Pokud požadujete kontext spuštění, který objekt nepodporuje, vrátí funkce CoCreateInstance kód chyby REGDB_E_CLASSNOTREG. Tento kód chyby může také znamenat, že CLSID neodpovídá žádné komponentě zaregistrované v počítači uživatele.

Pátý parametr v CoCreateInstance přijímá ukazatel na rozhraní. Vzhledem k tomu, že CoCreateInstance je obecný mechanismus, nemůže být tento parametr silně typován. Místo toho je datový typ void**a volající musí proměnit adresu ukazatele na typ void**. To je účel reinterpret_cast v předchozím příkladu.

Je důležité zkontrolovat návratové hodnoty coCreateInstance. Pokud funkce vrátí kód chyby, je ukazatel rozhraní COM neplatný a pokus o jeho dereferencování může způsobit pád programu.

Interně funkce CoCreateInstance používá různé techniky k vytvoření objektu. V nejjednodušším případě vyhledá identifikátor třídy v registru. Položka registru odkazuje na knihovnu DLL nebo EXE, která implementuje objekt. CoCreateInstance může také použít informace z katalogu COM+ nebo "side-by-side" (SxS) manifestu. Bez ohledu na to, že podrobnosti jsou pro volajícího transparentní. Další informace o interních podrobnostech CoCreateInstancenaleznete v tématu COM klienti a servery.

Shapes příklad, který jsme používali, je poněkud vykonstruovaný, takže teď se pojďme obrátit na skutečný příklad modelu COM v akci: zobrazení dialogového okna Otevřít, aby si uživatel mohl vybrat soubor.

Další

Příklad : Dialogové okno Otevřít