Megosztás a következőn keresztül:


Objektum létrehozása a COM-ban

Miután egy szál inicializálta a COM-kódtárat, a szál biztonságosan használhat COM-felületeket. COM-felület használatához a program először létrehoz egy objektum egy példányát, amely megvalósítja az adott felületet.

A COM-objektumok létrehozásának általában két módja van:

  • Az objektumot megvalósító modul olyan függvényt biztosíthat, amelyet kifejezetten az objektum példányainak létrehozásához terveztek.
  • Másik lehetőségként a COM egy CoCreateInstancenevű általános létrehozási függvényt is biztosít.

Vegyük például a hipotetikus Shape objektumot a témakörből Mi az a COM-felület?. Ebben a példában a Shape objektum egy IDrawablenevű felületet implementál. A Shape objektumot megvalósító grafikus kódtár az alábbi aláírással exportálhat egy függvényt.

// Not an actual Windows function. 

HRESULT CreateShape(IDrawable** ppShape);

Ebben a függvényben az alábbiak szerint hozhat létre egy új Shape objektumot.

IDrawable *pShape;

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

A ppShape paraméter típusa mutatóról mutatóraIDrawable. Ha korábban még nem látta ezt a mintát, a kettős közvetettség rejtélyes lehet.

Vegye figyelembe a CreateShape függvény követelményeit. A függvénynek vissza kell adnia egy IDrawable mutatót a hívónak. A függvény visszatérési értéke azonban már használatban van a hiba/siker kódhoz. Ezért a mutatót egy argumentumon keresztül kell visszaadni a függvénynek. A hívó egy IDrawable* típusú változót ad át a függvénynek, és a függvény felülírja ezt a változót egy új IDrawable mutatóval. A C++-ban egy függvénynek csak két módja van a paraméterérték felülírására: a hivatkozás alapján való átadás vagy a cím szerinti továbbítás. A COM az utóbbit használja, a pass-by-address módszert. A mutató címe pedig mutatóra mutató, így a paramétertípusnak IDrawable**kell lennie.

Az alábbiakban egy diagramot talál, amely szemlélteti a folyamatban lévő folyamatokat.

diagram kétmutatós indirekció

A CreateShape függvény a pShape (&pShape) címét használja, hogy új mutatóértéket írjon pShape.

CoCreateInstance: Az objektumok létrehozásának általános módja

A CoCreateInstance függvény általános mechanizmust biztosít az objektumok létrehozásához. A CoCreateInstancemegértéséhez ne feledje, hogy két COM-objektum implementálhatja ugyanazt a felületet, és egy objektum két vagy több felületet implementálhat. Így egy objektumokat létrehozó általános függvénynek két információra van szüksége.

  • Melyik objektumot kell létrehozni.
  • Melyik felületet kell az objektumból lekérni.

De hogyan jelezzük ezt az információt, amikor meghívjuk a függvényt? A COM-ban egy objektum vagy felület egy 128 bites szám hozzárendelésével azonosítható, amelyet globálisan egyedi azonosító (GUID) néven neveznek el. A GUID-ok olyan módon kerülnek létrehozásra, hogy valójában egyediek legyenek. A GRAFIKUS GUID-k megoldást jelentenek arra a problémára, hogyan hozhatók létre egyedi azonosítók központi regisztrációs szolgáltató nélkül. A GRAFIKUS GUID-ket néha univerzálisan egyedi azonosítóknak (UUID-k) nevezzük. A COM előtt a DCE/RPC-ben (Elosztott számítási környezet/Távoli eljáráshívás) használták őket. Számos algoritmus létezik az új GRAFIKUS GUID-k létrehozásához. Nem mindegyik algoritmus garantálja szigorúan az egyediséget, de annak valószínűsége, hogy véletlenül ugyanazt a GUID-értéket kétszer hozza létre, rendkívül kicsi – gyakorlatilag nulla. A GRAFIKUS GUID-k bármilyen entitás azonosítására használhatók, nem csak objektumok és felületek azonosítására. Ebben a modulban azonban csak ez a használat vonatkozik ránk.

A Shapes kódtár például két GUID-állandót deklarálhat:

extern const GUID CLSID_Shape;
extern const GUID IID_IDrawable; 

(Feltételezheti, hogy az állandók tényleges 128 bites numerikus értékei máshol vannak definiálva.) Az állandó CLSID_Shape azonosítja a Shape objektumot, míg az állandó IID_IDrawable azonosítja a IDrawable felületet. A "CLSID" előtag osztályazonosító, az IID előtag pedig felületazonosító. Ezek a COM-ban szabványos elnevezési konvenciók.

Ezeket az értékeket figyelembe véve az alábbiak szerint hozhat létre egy új Shape-példányt:

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.
}

A CoCreateInstance függvény öt paraméterből áll. Az első és negyedik paraméter az osztályazonosító és a felület azonosítója. Tulajdonképpen ezek a paraméterek azt mondják a függvénynek: "Hozd létre az Alakzat objektumot, és adj egy mutatót az IDrawable felületre."

Állítsa a második paramétert a NULL. (A paraméter jelentéséről további információt a COM dokumentációjában Összesítés című témakörben talál.) A harmadik paraméter olyan jelzőket használ, amelyek fő célja az objektum végrehajtási környezetének megadása. A végrehajtási környezet azt határozza meg, hogy az objektum ugyanabban a folyamatban fut-e, mint az alkalmazás; ugyanazon a számítógépen egy másik folyamatban; vagy távoli számítógépen. Az alábbi táblázat a paraméter leggyakoribb értékeit mutatja be.

Zászló Leírás
CLSCTX_INPROC_SERVER Ugyanaz a folyamat.
CLSCTX_LOCAL_SERVER Más folyamat, ugyanaz a számítógép.
CLSCTX_REMOTE_SERVER Másik számítógép.
CLSCTX_ALL Használja az objektum által támogatott leghatékonyabb lehetőséget. (A rangsor a leghatékonyabbtól a legkevésbé hatékonyig a következő: folyamatban lévő, folyamaton kívüli és számítógépközi.)

 

Egy adott összetevő dokumentációja meg tudja állapítani, hogy az objektum mely végrehajtási környezetet támogatja. Ha nem, használja a CLSCTX_ALL. Ha olyan végrehajtási környezetet kér, amelyet az objektum nem támogat, a CoCreateInstance függvény a REGDB_E_CLASSNOTREGhibakódot adja vissza. Ez a hibakód azt is jelezheti, hogy a CLSID nem felel meg a felhasználó számítógépén regisztrált összetevőknek.

A CoCreateInstanceötödik paramétere a felületre mutató mutatót kap. Mivel CoCreateInstance egy általános mechanizmus, ezt a paramétert nem lehet erősen begépelni. Ehelyett az adattípus void**, és a hívónak a mutató címét egy void** típusra kell konvertálnia. Ez az előző példában szereplő reinterpret_cast célja.

Fontos ellenőrizni CoCreateInstancevisszatérési értékét . Ha a függvény hibakódot ad vissza, a COM-felület mutatója érvénytelen, és a hivatkozás megkísérlése ez a program összeomlását okozhatja.

A CoCreateInstance függvény belsőleg különböző technikákkal hoz létre objektumokat. A legegyszerűbb esetben megkeresi az osztályazonosítót a beállításjegyzékben. A beállításjegyzék-bejegyzés egy OLYAN DLL-re vagy EXE-re mutat, amely megvalósítja az objektumot. CoCreateInstance com+ katalógusból vagy egymás melletti (SxS) jegyzékből származó információkat is használhat. A részletek ettől függetlenül transzparensek a hívó számára. A CoCreateInstancebelső részleteiről további információt COM-ügyfelek és kiszolgálókcímű cikkben talál.

Az általunk használt Shapes példa kissé mesterkélt, ezért most nézzünk meg egy valós példát a COM működésére: megjelenítjük a Megnyitás párbeszédpanelt, amely lehetővé teszi a felhasználó számára, hogy kiválasszon egy fájlt.

Következő

Példa: A Párbeszédpanel megnyitása