4.3. Rozhraní komponenty

Komponentní model COM je založen na využití rozhraní, pomocí nichž komponenta komunikuje se svým okolím. Na rozdíl od jiných modelů (CORBA, JavaBeans) je toto rozhraní definováno až na binární úrovni, takže umožňuje efektivní komunikaci s komponentami psanými v různých programovacích jazycích. Rozhraní COM je tvořeno pouze metodami, takže i přístup k datům je realizován výlučně voláním metod, což umožňuje zcela oddělit implementaci komponent od aplikací, které tyto komponenty využívají.

Definice binární struktury rozhraní COM komponent vychází z mechanismu, který se například v jazyce C++ používá pro volání virtuálních metod. Toto volání pro nějaký konkrétní objekt probíhá tak, že se nejprve získá ukazatel na tabulku virtuálních metod, jenž je součástí instance objektu. Tato tabulka je vlastně pole ukazatelů na kódy konkrétních metod, takže známe-li pořadové číslo volané metody, vyzvedneme z tablky adresu jejího kódu a metodu provedeme. Tento postup je znázorněn na následujícím příkladu.

Předpokládejme, že máme objekt se dvěma virtuálními metodami. Tabulka virtuálních metod tedy bude mít dvě položky, obsahující ukazatele na kód těchto dvou metod.

Obrázek 4.3. Tabulka virtuálních metod

Velmi podstatnou vlastností takto zvolené struktury je to, že jsme schopni ji vytvořit i v dalších jazycích. Například v jazyce C bychom mohli použít následujícího řešení:

struct Komponenta {
   void** _vmt;     // ukazatel na VMT
   int    var_1;    // další instanční proměnné
   int    var_2;
   ...
};

// implementace metod
void Komponenta_metoda1(struct Komponenta* _this, int arg) { ... }
int  Komponenta_metoda2(struct Komponenta* _this) { ... }

// tabulka virtuálních metod
void* Komponenta__vmt[] = { <Komponenta_Start, <Komponenta_Next };

Pomocí vícenásobné dědičnosti můžeme dokonce zařídit i to, aby jedna komponenta mohla implementovat více rozhraní, například můžeme definovat prozhraní pro generátory čísel s různými rozloženími a všechna tato rozhraní implementovat jedinou komponentou. V tom případě bude ke každému implementovanému rozhraní vytvořena samostatná tabulka virtuálních metod, přes kterou se dostaneme ke konkrétním metodám implementujícím dané rozhraní. Na druhé straně může existovat více komponent, které implementují totéž rozhraní, například od různých výrobců. K tomu, abychom zajistili co nejvolnější vazbu mezi aplikací a komponentami, které používá, právě slouží specifikace COM.