Tidlig og sen binding i automatisering

Artikkeloversettelser Artikkeloversettelser
Artikkel-ID: 245115 - Vis produkter som denne artikkelen gjelder for.
Vis alt | Skjul alt

På denne siden

Sammendrag

Bindingene til en automatiseringsserver kan påvirke mange ting i programmet, for eksempel ytelse, fleksibilitet og tilpasningsdyktighet.

I denne artikkelen gir vi en oversikt over tilgjengelige bindingstyper for automatiseringsklienter og presenterer argumenter for og imot hver av disse.

Mer informasjon

Automatisering er en prosess der en programvarekomponent kommuniserer med og/eller styrer en annen programvarekomponent ved hjelp av Microsofts Component Object Model (COM). Dette er utgangspunktet for nesten all kommunikasjonen mellom komponenter i språk som Visual Basic og Visual Basic for Applications, og har blitt en vanlig bestanddel i de fleste programmer.

Historisk sett er et automatiseringsobjekt ethvert objekt som støtter IDispatch-grensesnittet. Dette grensesnittet gjør det mulig for klienter å kalle metoder og egenskaper på kjøretidspunktet uten at det er nødvendig å vite nøyaktig hvilket objekt de skal kommunisere med, på forhånd. Denne prosessen kalles sen binding. I dag brukes imidlertid uttrykket automatiseringsobjekt om så godt som alle slags COM-objekter, også de som ikke støtter IDispatch, og som derfor ikke kan brukes med sen binding. I denne artikkelen tar vi utgangspunkt i at objektet du skal automatisere, støtter begge bindingsmetodene.

Hva er binding?

Binding er en prosess som går ut på å koble funksjonskallene som programmereren har skrevet, til den faktiske, interne eller eksterne, koden som brukes til å implementere funksjonen. Dette skjer ved kompilering av programmet, og alle funksjoner som kalles i koden, må bindes før koden kan kjøres.

Denne prosessen blir lettere å forstå hvis vi sammenligner bindingen med produksjon av en bok. Tenk deg koden som teksten i en bok. I et av avsnittene finner du henvisningen "du kan lese mer om dette i kapittel 12, side x". Du vet ikke hva det faktiske sidetallet blir, før boken er ferdig. Det betyr at for at henvisningen skal bli riktig, må først sidene i boken bindes sammen, slik at riktig sidetall kan settes inn i henvisningen. Du må vente på at boken er bundet sammen, før du kan henvise til andre deler av den.

Dette kan sammenlignes med binding av programvare. Koden består av deler som må settes sammen før den kan "leses". Binding vil si å erstatte funksjonsnavn med minneadresser (eller minneforskyvninger) som koden "hopper til" når funksjonen kalles. Når det gjelder COM-objekter, er adressen en minneforskyvning i en pekertabell (v-tabellen) som er lagret i objektet. Når en COM-funksjon bindes, skjer dette via v-tabellen.

COM-objektene har en enkel oppbygning. Når koden inneholder en referanse til et objekt, inneholder den en indirekte peker til toppen av v-tabellen. V-tabellen er en samling minneadresser der hver oppføring er en ny funksjon som kan kalles på det aktuelle objektet. Hvis du vil kalle den tredje funksjonen for et COM-objekt, går du tre oppføringer ned i tabellen og hopper til minneplasseringen som er angitt der. Da kjøres koden for funksjonen før kjøring av neste kodelinje.

+-[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 |     :
                       :             +----------------------------+     :
                       +................................................+

				
Eksemplet ovenfor viser hva som skjer når et COM-objekt frigis. Fordi alle COM-objekter arver fra IUnknown, er de tre første oppføringene i tabellen metoder for IUnknown. Når du har behov for å frigjøre et objekt, kaller koden den tredje funksjonen i v-tabellen (IUnknown::Release).

Dette gjøres i bakgrunnen av Visual Basic. Som Visual Basic-programmerer vil du aldri ha behov for å håndtere v-tabeller direkte. Men denne bindingsstrukturen er felles for alle COM-objekter, så for å forstå hva binding er, er det likevel viktig at du kjenner til den.

Tidlig binding

Eksemplet ovenfor viser det som kalles tidlig binding eller v-tabellbinding. Denne bindingstypen brukes når et COM-objekts IUnknown-grensesnitt kalles. Dette er likt for alle COM-objekter. Men hva med objektets øvrige funksjoner? Hvordan kaller du objektets oppdateringsmetode eller egenskaper for overordnede objekter? Dette er egendefinerte funksjoner som vanligvis er unike for et objekt. Hvordan finner du funksjonsadressene du trenger for å kalle dem, hvis du ikke kan gjette deg til plasseringene i v-tabellen?

Svaret avhenger selvsagt av om du vet hvordan objektets v-tabell ser ut på forhånd. Hvis du gjør det, kan du bruke samme prosess for tidlig binding til objektets egendefinerte metoder som til IUnknown-metodene. Det er dette som kalles tidlig binding.

Hvis du skal bruke tidlig binding på et objekt, må du først vite hvordan objektets v-tabell ser ut. I Visual Basic kan du gjøre dette ved å legge inn en henvisning til et typebibliotek som beskriver objektet, objektets grensesnitt (v-tabellen) og alle funksjonene som kan kalles på objektet. Når dette er gjort, kan du angi at objektet er av en bestemt type, og deretter angi og bruke objektet ved hjelp av v-tabellen. Hvis du for eksempel vil automatisere Microsoft Office Excel ved hjelp av tidlig binding, legger du til en referanse i objektbiblioteket for Microsoft Excel 8.0 fra dialogboksen Project|References og angir deretter at variabelen er av typen Excel.Application. Da vil alle fremtidige kall til objektet ha tidlig binding:
' 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
				
Denne metoden fungerer bra i de fleste tilfeller, men hva gjør du hvis du ikke vet nøyaktig hvilket objekt du kommer til å bruke, på utformingstidspunket? Hva om du må kommunisere med flere Excel-versjoner, eller kanskje med et helt ukjent objekt?

Sen binding

COM inkluderer IDispatch. Objekter som implementerer IDispatch, har et såkalt visningsgrensesnitt (hvis dette er det eneste grensesnittet de støtter) eller dobbelt grensesnitt (hvis de også har et egendefinert grensesnitt som du kan opprette en tidlig binding til). Om klienter som binder til IDispatch, sier vi at de har sene bindinger, fordi de bruker IDispatch-metodene til å avgjøre nøyaktig hvilken egenskap eller metode de skal kalle, på kjøretidspunktet. Hvis vi går tilbake til bokeksemplet vi brukte tidligere, kan vi sammenligne det med en fotnote som henviser til innholdsfortegnelsen, slik at du må slå opp sidetallet, i stedet for at sidetallet er satt inn i teksten på forhånd.

Grensesnittets virkemåte styres av to funksjoner: GetIDsOfNames og Invoke. Den første tilordner funksjonsnavn (strenger) til en ID (også kalt dispid) som representerer funksjonen. Når du kjenner IDen til funksjonen du vil kalle, kan du kalle den ved hjelp av Invoke-funksjonen. Denne typen metodeaktivering kalles sen binding.

I Visual Basic brukes som tidligere nevnt objekterklæringen til å angi hvordan et objekt skal bindes. Hvis du angir en objektvariabel som "Object", gir du Visual Basic beskjed om å bruke IDispatch, og altså sen binding:
' 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
				
Som du ser, er den øvrige koden den samme. Når det gjelder koden du skriver, ligger den eneste forskjellen mellom tidlig og sen binding i variabelerklæringen.

Det er viktig å merke seg at det er funksjonen som kalles, og ikke måten den kalles på, som har en sen binding. Fra de foregående avsnittene om binding, bør du merke deg at IDispatch i seg selv har tidlig binding. Med det mener vi at Visual Basic kaller at egenskapen Visible skal angis, via en oppføring i v-tabellen (IDispatch::Invoke), på samme måte som med alle COM-kall. COM-objektet må selv videresende kallet til den korrekte funksjonen for at Excel skal bli synlig. Denne omveien betyr at Visual Basic-klienten kan kompileres (det vil si bindes til en gyldig funksjonsadresse) før det er kjent nøyaktig hvilken funksjon som skal gjøre jobben.

Dispid-binding

Enkelte automatiseringsklienter (særlig MFC og Visual Basic 3.0, men også Visual Basic 5.0 og 6.0 hvis vi tenker på ActiveX-kontroller) bruker en hybridform for sen binding som kalles dispid-binding. Hvis et COM-objekt er kjent på utformingstidspunktet, kan dispidene for funksjonene som kalles, hurtigbufres og sendes rett til IDispatch::Invoke uten at det er behov for å kalle GetIDsOfNames på kjøretidspunktet. Siden du bare trenger å gjøre ett COM-kall per funksjon, og ikke to, kan dette øke ytelsen dramatisk.

Dispid-binding er ikke et alternativ du vanligvis kan velge i Visual Basic 5.0 eller 6.0. Det brukes til objekter som føres opp i et typebibliotek, men som ikke har noe egendefinert grensesnitt (det vil si for objekter som bare har visningsgrensesnitt) og for aggregerte ActiveX-kontroller, men generelt sett bruker Visual Basic tidlig binding der du vanligvis ville ha brukt dispid-binding.

Hva slags binding bør jeg bruke?

Svaret på dette spørsmålet avhenger fremfor alt av prosjektets utforming. Microsoft anbefaler å bruke tidlig binding i de aller fleste tilfeller. Det kan imidlertid være grunner som tilsier bruk av sen binding.

Tidlig binding er den foretrukne metoden. Denne gir best ytelse fordi programmet bindes direkte til adressen til funksjonen som kalles, og det derfor ikke legges beslag på ekstra ressurser på kjøretidspunktet. Ser vi på samlet kjøretid, er denne metoden minst dobbelt så rask som sen binding.

Tidlig binding gir dessuten typesikkerhet. Når du angir en referanse til komponentens typebibliotek, gir Visual Basic IntelliSense-støtte som gjør det enklere å kode alle funksjonene riktig. Visual Basic gir deg dessuten en advarsel hvis datatypen til en parameter eller returverdi er feil, og sparer deg dermed mye tid ved skriving og feilsøking av kode.

Likevel er sen binding nyttig i situasjoner der objektets nøyaktige grensesnitt ikke er kjent på utformingstidspunktet. Hvis programmet skal kommunisere med flere ukjente servere, eller har behov for å aktivere funksjoner etter navn (for eksempel ved hjelp av Visual Basic 6.0 CallByName), må du bruke sen binding. Sen binding er dessuten nyttig for å omgå problemer med kompatibilitet med ulike versjoner av en komponent der grensesnittet har blitt endret eller tilpasset fra versjon til versjon.

Fordelene med tidlig binding betyr at du bør bruke dette der det er mulig.

Sikre kompatibilitet fra versjon til versjon

Hvis du bruker en komponent som ikke distribueres sammen med installasjonspakken, og du dermed ikke kan være sikker på hvilken versjon komponenten kommer til å kommunisere med på kjøretidspunktet, bør du være spesielt oppmerksom på tidlig binding til et grensesnitt som er kompatibelt med alle versjoner av komponenten, eller (i enkelte tilfeller) bruke sen binding til å kalle en metode som kan forekomme i en bestemt versjon, og mislykkes hvis denne metoden ikke finnes i versjonen som er installert på klientsystemet.

Microsoft Office-programmene er et godt eksempel på denne typen COM-servere. Grensesnittet i Office-programmer utvides gjerne fra versjon til versjon, nye funksjoner kommer til og tidligere feil og mangler blir rettet opp. Hvis du vil automatisere et Office-program, anbefaler vi å bruke tidlig binding til den tidligste versjonen av produktet du regner med kan være installert på klientsystemet. Hvis du for eksempel skal automatisere Excel 95, Excel 97, Excel 2000 og Excel 2002, bruker du typebiblioteket for Excel 95 (XL5en32.olb) for å sikre kompatibilitet med alle versjonene.

Office-programmene viser også at objektmodeller med store todelte grensesnitt kan ha begrensninger med hensyn til formidlinger på enkelte plattformer. Hvis du vil sikre deg at koden fungerer best mulig på alle plattformer, bør du bruke IDispatch. Hvis du vil ha mer informasjon om hvordan du kan sikre kompatibilitet ved arbeid med Office-programmer, klikker du artikkelnummeret nedenfor for å vise artikkelen i Microsoft Knowledge Base:
247579 Bruke DISPID-binding så langt det er mulig, ved automatisering av Office-programmer (denne artikkelen kan være på engelsk)

Referanser

Hvis du vil vite mer om COM, v-tabeller og automatisering, kan du se følgende bøker:
Rogerson, Dale, Inside COM, MSPRESS, ISBN: 1-57231-349-8.

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

Egenskaper

Artikkel-ID: 245115 - Forrige gjennomgang: 23. november 2007 - Gjennomgang: 7.1
Informasjonen i denne artikkelen gjelder:
  • Microsoft Office Ultimate 2007
  • Microsoft Office Enterprise 2007
  • Microsoft Office Professional 2007
  • Microsoft Office Professional Plus 2007
  • Microsoft Office Standard 2007
  • Microsoft Office Home and Student 2007
  • Microsoft Office Basic 2007
  • Microsoft Office Standard Edition 2003
  • Microsoft Office XP Developer Edition
  • Microsoft Office 2000 Developer Edition
  • Microsoft Visual Basic 5.0 Professional Edition
  • Microsoft Visual Basic 6.0 Professional Edition
  • Microsoft Visual Basic 5.0 Enterprise Edition
  • Microsoft Visual Basic 6.0 Enterprise Edition
Nøkkelord: 
kbinfo kbautomation KB245115

Gi tilbakemelding

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com