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


Korai és késői kötés használata az Automationben

Összefoglalás

Az Automation-kiszolgálóhoz való kötés számos dologra hatással lehet a programban, például a teljesítményre, a rugalmasságra és a karbantarthatóságra.

Ez a cikk az Automation-ügyfelek számára elérhető kötéstípusokat ismerteti, és az egyes módszerek mindkét oldalát mérlegeli.

További információ

Az automatizálás egy olyan folyamat, amelyben egy szoftverösszetevő kommunikál és/vagy vezérel egy másik szoftverösszetevőt a Microsoft Component Object Model (COM) használatával. Ez az alapja a legtöbb összetevőre kiterjedő kommunikációnak, amelyet olyan nyelveken használnak, mint a Visual Basic vagy a Visual Basic for Applications, és a legtöbb program normál részévé vált.

Az Automation-objektumok korábban olyan objektumok, amelyek támogatják az IDispatch felületet. Ez a felület lehetővé teszi az ügyfelek számára, hogy futásidőben hívjanak metódusokat és tulajdonságokat anélkül, hogy ismerniük kellene a pontos objektumot, amellyel a tervezéskor kommunikálnak; egy késői kötés nevű folyamat. Napjainkban azonban az Automation-objektum kifejezés gyakorlatilag bármely COM-objektumra alkalmazható, még azokra is, amelyek nem támogatják az IDispatch használatát (és ezért nem lehet késői kötés). Ez a cikk feltételezi, hogy az automatizálni kívánt objektum mindkét kötési metódust támogatja.

Mi az a kötés?

A kötés egy olyan folyamat, amellyel a programozó függvényhívásokat ír a függvényt megvalósító tényleges kódhoz (belső vagy külső). Ez az alkalmazás lefordításakor történik, és a kódban meghívott összes függvényt kötelező megadni a kód végrehajtása előtt.

A folyamat megértéséhez gondoljon a "kötésre" a könyv közzététele szempontjából. Képzelje el, hogy a kód olyan, mint a könyv szövege, ahol egy bizonyos bekezdésben a következőhöz hasonlót írt: "lásd a 12. fejezetet, x. oldal a további részletekért". Nem tudja, mi az oldalszám, amíg a könyv be nem fejeződik, így mielőtt a bekezdést a kívánt módon felolvassa, a könyv összes oldalát össze kell kötni, és be kell szúrni a megfelelő oldalszámot a bekezdésbe. Várjon, amíg a könyv "kötött", mielőtt hivatkozhat a könyv más részeire.

A kötési szoftverek hasonlóak. A kód olyan részekből áll, amelyeket össze kell állítani a kód "olvasása" előtt. A kötés a függvénynevek memóriacímekre (pontosabban memóriaeltolásokra) cserélése, ahol a kód a függvény meghívásakor "oda ugrik". COM-objektumok esetén a cím az objektum által tárolt mutatótáblák (úgynevezett v-tábla) memóriaeltolása. Com-függvény kötöttség esetén a v-táblán keresztül van kötve.

A COM-objektumok szerkezete egyszerű. Ha a kód egy objektumra mutató hivatkozást tárol, az közvetett mutatót tartalmaz a v-tábla tetejére. A v-tábla memóriacímek tömbje, ahol minden bejegyzés egy másik függvény, amely meghívható az objektumon. Ha egy COM-objektum harmadik függvényét szeretné meghívni, ugorjon le három bejegyzésre a táblázatban, majd ugorjon az ott megadott memóriahelyre. Ez végrehajtja a függvény kódját, és amikor elkészült, visszaküldi Önt, készen áll a következő kódsor végrehajtására.

+-[Code]------------+  +.................................[COM Object]...+
|                   |  : +-------------+                                :
|Set obj = Nothing -|--->| obj pointer |                                :
|                   |  : +-|-----------+                                :
+-------------------+  :   |   +-----------------+                      :
                       :   +-->| v-table pointer |                      :
                       :       +--|--------------+                      :
                       :          |                                     :
                       :          |  +----------------------------+     :
                       :  (3rd)   |  | Function 1 Address pointer |     :
                       : (Offset) |  +----------------------------+     :
                       :          |  | Function 2 Address pointer |     :
                       :          |  +----------------------------+     :
                       :          +->| Function 3 Address pointer |     :
                       :             +----------------------------+     :
                       +................................................+

A fenti példa bemutatja, mi történik egy COM-objektum felszabadításakor. Mivel az összes COM-objektum az IUnknown objektumtól öröklődik, a táblázat első három bejegyzése az IUnknown metódusa. Ha ki kell szabadítania egy objektumot, a kód meghívja a v-tábla harmadik függvényét (IUnknown::Release).

Szerencsére ezt a munkát a Visual Basic végzi a színfalak mögött. Visual Basic-programozóként soha nem kell közvetlenül v-táblázattal foglalkoznia. De ez a struktúra az összes COM-objektum kötése, és fontos, hogy tisztában legyen vele, mi a kötés.

Korai kötés

A fenti példa az úgynevezett korai (vagy v-table) kötés. Minden COM-objektum esetében ez a kötési forma akkor jön létre, amikor a COM-objektum IUnknown felületét meghívják. De mi a helyzet az objektum többi függvényével? Hogyan hívható meg a Refresh metódus vagy annak szülőtulajdonsága? Ezek egyéni függvények, amelyek jellemzően egy objektumra jellemzően egyediek. Ha a v-táblában lévő helyüket nem lehet feltételezni, hogyan találhatja meg a hívásukhoz szükséges függvénycímeket?

A válasz természetesen attól függ, hogy előre tudja-e, hogyan néz ki az objektum v-táblázata. Ha így tesz, ugyanezt a korai kötési folyamatot hajthatja végre az objektum egyéni metódusaival, mint az IUnknown metódusaival. Általában ezt jelenti a "korai kötés".

Ha korai kötést szeretne használni egy objektumon, ismernie kell a v-tábla megjelenését. A Visual Basicben ezt úgy teheti meg, hogy egy olyan típustárra mutató hivatkozást ad hozzá, amely leírja az objektumot, annak felületét (v-table) és az objektumon meghívható összes függvényt. Ha ez megtörtént, deklarálhat egy objektumot egy bizonyos típusként, majd beállíthatja és használhatja azt a v-tábla használatával. Ha például korai kötéssel szeretné automatizálni a Microsoft Office Excelt, akkor a Projectből fel kell vennie egy hivatkozást a "Microsoft Excel 8.0 objektumtárra"| Hivatkozások párbeszédpanel, majd deklarálja a változót "Excel.Application" típusúként. Ettől kezdve az objektumváltozóhoz intézett összes hívás korai kötésű lesz:


' Set reference to 'Microsoft Excel 8.0 Object Library' in
' the Project|References dialog (or Tools|References for VB4 or VBA).

' Declare the object as an early-bound object
  Dim oExcel As Excel.Application

  Set oExcel = CreateObject("Excel.Application")

' The Visible property is called via the v-table
  oExcel.Visible = True

Ez a módszer az idő nagy részében jól működik, de mi a teendő, ha nem tudja pontosan, hogy pontosan milyen objektumot fog használni a tervezéskor? Mi a teendő például, ha az Excel több verziójával vagy esetleg egy "ismeretlen" objektummal szeretne beszélni?

Késői kötés

A COM tartalmazza az IDispatch-et. Az IDispatch-et megvalósító objektumokról azt mondják, hogy dispinterface (ha ez az egyetlen felület, amelyet támogatnak) vagy kettős felülettel rendelkeznek (ha olyan egyéni felülettel is rendelkeznek, amelyhez korai kötést lehet kötni). Az IDispatch-hez kötődő ügyfelek "késői kötésűnek" minősülnek, mert a meghívott pontos tulajdonság vagy metódus futásidőben van meghatározva az IDispatch metódusainak használatával. Visszatérve a könyv példájára, gondoljon rá úgy, mint egy lábjegyzetre, amely a tartalomjegyzékhez irányítja, ahol az oldalszámot "olvasási időben" kell "megkeresnie" ahelyett, hogy már kinyomtatta volna a szövegben.

A felület varázsát két függvény vezérli: GetIDsOfNames és Invoke. Az első függvényneveket (sztringeket) egy azonosítóra (más néven dispidre) képezi le, amely a függvényt jelöli. Ha már ismeri a meghívni kívánt függvény azonosítóját, meghívhatja a Hívás függvénnyel. A metódushívásnak ezt a formáját "késői kötésnek" nevezzük.

A Visual Basicben ismét az objektum deklarációja határozza meg, hogy az objektum hogyan legyen kötve. Ha egy objektumváltozót "Objektumként" deklarál, valójában arra utasítja a Visual Basicet, hogy használja az IDispatch-et, ezért késői kötés:

' No reference to a type library is needed to use late binding.
' As long as the object supports IDispatch, the method can 
' be dynamically located and invoked at run-time.

' Declare the object as a late-bound object
  Dim oExcel As Object

  Set oExcel = CreateObject("Excel.Application")

' The Visible property is called via IDispatch
  oExcel.Visible = True

Mint látható, a kód többi része ugyanaz. A korai kötés és a késői kötés közötti egyetlen különbség (a megírt kód szempontjából) a változódeklarációban van.

Fontos megjegyezni, hogy a "késői kötés" a meghívandó függvény, nem pedig a hívás módja. A kötésről szóló korábbi, általános vita során megfigyelheti, hogy maga az IDispatch is "early bound:", azaz azt, hogy a Visual Basic egy v-table bejegyzésen (IDispatch::Invoke) keresztül állítja be a Visible tulajdonságot, mint bármely COM-hívást. Maga a COM objektum felelős azért, hogy a hívást a megfelelő függvényhez irányítsa, hogy láthatóvá tegye az Excelt. Ez a közvetettség lehetővé teszi, hogy a Visual Basic-ügyfél lefordítható legyen (azaz érvényes függvénycímhez legyen kötve), de még mindig nem tudja pontosan azt a függvényt, amely ténylegesen elvégzi a munkát.

Leválasztott kötés

Egyes Automation-ügyfelek (leginkább MFC és Visual Basic 3.0, de az ActiveX-vezérlők tekintetében a Visual Basic 5.0 és 6.0 is) a késői kötés egy hibrid formáját, az úgynevezett dispid kötést használják. Ha a COM-objektum a tervezéskor ismert, a meghívott függvények dispids parancsai gyorsítótárazhatók, és közvetlenül továbbíthatók az IDispatch::Invoke metódusnak anélkül, hogy a GetIDsOfNames metódust futásidőben kellene meghívni. Ez jelentősen növelheti a teljesítményt, mivel ahelyett, hogy függvényenként két COM-hívást indítanának, csak egyet kell kezdeményeznie.

A leválasztott kötés általában nem választható a Visual Basic 5.0-s vagy 6.0-s verziójában. Olyan objektumokhoz használatos, amelyek egy típustárban hivatkoznak rá, de nem tartalmaznak egyéni felületet (azaz csak dispinterface objektumokat), valamint aggregált ActiveX-vezérlőkhöz, de a Visual Basic általában korai kötést használ minden olyan helyen, ahol általában nem használna különálló kötést.

Milyen kötési formát használjak?

A kérdésre adott válasz a projekt kialakításától függ, mint bármi más. A Microsoft szinte minden esetben korai kötést javasol. Előfordulhat azonban, hogy a késői kötést választja.

A korai kötés az előnyben részesített módszer. Ez a legjobb teljesítmény, mert az alkalmazás közvetlenül a meghívott függvény címéhez kötődik, és a futásidejű keresés nem jár többletterheléssel. A teljes végrehajtási sebesség tekintetében legalább kétszer olyan gyors, mint a késői kötés.

A korai kötés a típusbiztonságot is biztosítja. Ha az összetevő típustárához van referenciája, a Visual Basic intelliSense-támogatást nyújt az egyes függvények helyes kódolásához. A Visual Basic arra is figyelmeztet, ha egy paraméter vagy a visszatérési érték adattípusa helytelen, így sok időt takarít meg a kód írásakor és hibakeresésekor.

A késői kötés akkor is hasznos, ha az objektum pontos felülete nem ismert a tervezéskor. Ha az alkalmazás több ismeretlen kiszolgálóval szeretne beszélni, vagy név szerint szeretne függvényeket meghívni (például a Visual Basic 6.0 CallByName függvény használatával), akkor késői kötést kell használnia. A késői kötés az összetevők több verziója közötti kompatibilitási problémák megoldásához is hasznos, amelyek nem megfelelően módosították vagy módosították a felületét a verziók között.

A korai kötés előnyei a legjobb választást teszik, amikor csak lehetséges.

Kompatibilitás fenntartása több verzióban

Ha olyan összetevőt fog használni, amelyet nem terjeszt újra a telepítőcsomaggal, és nem biztos abban, hogy pontosan melyik verzióval fog kommunikálni futásidőben, különös figyelmet kell fordítania az összetevő összes verziójával kompatibilis felülethez való korai kötésre, vagy (bizonyos esetekben) késői kötés használatával meghívhat egy metódust, amely egy adott verzióban létezhet, és szabályosan meghiúsulhat, ha ez a módszer nincs jelen az ügyfélrendszerre telepített verzióban.

A Microsoft Office-alkalmazások jó példával szolgálnak az ilyen COM-kiszolgálókra. Az Office-alkalmazások általában kibővítik a felületüket, hogy új funkciókat adjanak hozzá, vagy kijavítsák a verziók közötti korábbi hiányosságokat. Ha automatizálnia kell egy Office-alkalmazást, javasoljuk, hogy korai kötéssel rendelje hozzá a termék azon legkorábbi verzióját, amely várhatóan telepítve lesz az ügyfél rendszerében. Ha például az Excel 95, az Excel 97, az Excel 2000 és az Excel 2002 automatizálására van szükség, akkor az Excel 95 (XL5en32.olb) típustárával kell fenntartania a kompatibilitást mindhárom verzióval.

Az Office-alkalmazások azt is bemutatják, hogy a nagy kettős felülettel rendelkező objektummodellek bizonyos platformokon korlátozottak lehetnek a rendezésben. Ahhoz, hogy a kód az összes platformon a legjobban működjön, használja az IDispatch-et.

Hivatkozások

A COM-ról, a v-táblákról és az Automation használatáról az alábbi könyvekben talál további információt:

Rogerson, Dale, Inside COM, MSPRESS, ISBN: 1-57231-349-8.

Curland, Matt, Advanced Visual Basic 6, DevelopMentor, 0201707128.