Komponentobjektmodell
Component Object Model (COM) er en Microsoft -plattform for programvarekomponenter , introdusert i 1993 . Denne plattformen brukes til å tillate kommunikasjon mellom prosesser og dynamisk opprettelse av objekter, i et hvilket som helst programmeringsspråk som støtter denne teknologien. Begrepet COM brukes ofte i verden av programvareutvikling som en paraplybetegnelse for OLE, OLE Automation, ActiveX, COM+ og DCOM-teknologier. Selv om COM ble introdusert i 1993, la ikke Microsoft vekt på COM-navnet før i 1997.
I hovedsak er COM en måte å implementere språknøytrale objekter på, slik at de kan brukes i andre miljøer enn det de ble opprettet i, på tvers av maskingrenser. For godt skapte komponenter tillater COM gjenbruk av objekter uten kunnskap om deres interne implementering, fordi det tvinger komponentimplementere til å gi veldefinerte grensesnitt som er atskilt fra implementeringen. Ulik minnetildelingssemantikk blir imøtekommet ved å gjøre objekter ansvarlige for egen skapelse og ødeleggelse via referansetellingen. Du kan caste mellom ulike grensesnitt for et objekt ved å bruke QueryInterface(). Den foretrukne metoden for arv i COM er opprettelsen av underobjekter som metodekall delegeres til (kalt aggregering).
Selv om disse teknologiene har blitt implementert på mange plattformer, brukes de først og fremst med et Microsoft Windows- program . COM forventes å bli erstattet, i det minste til en viss grad, av Microsoft .NET , og støtte for webtjenester gjennom Windows Communication Foundation (WCF). Network DCOM bruker proprietære binære formater, mens WCF bruker XML - baserte SOAP- meldinger . COM konkurrerer også med CORBA og JavaBeans som et programvarekomponentsystem.
Tekniske detaljer
COM-programmerere bygger programvare ved å bruke COM-bevisste programvarekomponenter. Ulike typer komponenter identifiseres av type-ID-er (CLSID-er), som er globalt unike identifikatorer, eller GUID-er. Hver COM-komponent avslører sin funksjonalitet gjennom ett eller flere grensesnitt. De forskjellige grensesnittene som støttes av en komponent skilles fra hverandre ved å bruke grensesnitt-ID-er (IID-er), som også er GUID-er.
COM-grensesnitt har implementeringer på forskjellige språk, som C, C++, Visual Basic og flere av skriptspråkene implementert på Windows-plattformen. All tilgang til komponentene skjer gjennom metodene til grensesnittene. Dette tillater teknikker som interprosessering, til og med programmering på tvers av datamaskiner (sistnevnte gjennom DCOM-støtte).
Grensesnitt
Alle COM-komponenter må implementere minst standard IUnknown -grensesnitt , og dermed er alle COM-grensesnitt avledet fra IUnknown . IUnknown -grensesnittet består av tre metoder: AddRef()og Release(), som implementerer referansetelling og grensesnittlivssykluskontroll; og QueryInterface(), som ved å spesifisere en IID tillater et anrop for å hente referanser til de forskjellige grensesnittene som komponenten implementerer. Effekten av QueryInterface()er lik dynamic_cast <>i C++ eller castingi C# og Java.
Grensesnittene til en COM-komponent er nødvendig for å vise de refleksive, symmetriske og transitive egenskapene. Den reflekterende egenskapen refererer til muligheten for kallet til QueryInterface(), gitt et grensesnitt med grensesnitt-IDen, til å returnere den samme forekomsten av grensesnittet. Den symmetriske egenskapen refererer til det faktum at når grensesnitt B hentes fra grensesnitt A av QueryInterface(), så kan grensesnitt A også hentes fra grensesnitt B. Den transitive egenskapen ligner den symmetriske egenskapen, men krever at dersom grensesnitt B kan hentes fra A, og C i sin tur fra B, så skal grensesnitt C være tilgjengelig fra A.
Et grensesnitt består av en virtuell funksjonspeker som inneholder en liste over pekere til funksjonene som funksjonen deklarert i grensesnittet implementerer, i samme rekkefølge som de ble deklarert i grensesnittet. Denne teknikken for pekeroverføring av strukturfunksjoner er veldig lik den som brukes av OLE 1.0 for å kommunisere med biblioteksystemet.
COM spesifiserer mange andre standardgrensesnitt som brukes for å tillate kommunikasjon mellom komponenter. En av dem er for eksempel IStream , som er ment for komponenter som har datastrømsemantikk (en FileStream -komponent som brukes til å lese og skrive filer). Den har de forventede lese- og skrivemetodene for å utføre strømlesing og skriving. Et annet standard grensesnitt er IOleObject , som er beregnet på komponenter som forventer å bli bundet eller innebygd i en container. IOleObject inneholder metoder som lar interessenter bestemme størrelsen på en rektangelkomponents grenser, hvis komponenten støtter operasjoner som 'Åpne' , 'Lagre' og så videre.
Klasser
En klasse i COM kalles en coclass , som er kontraktsformen for Component Object-klassen . En coclass er COMs måte å definere en klasse i språkuavhengig, objektorientert forstand. En coclass leverer en konkret implementering av ett eller flere grensesnitt. I COM kan slike konkrete implementeringer skrives i et hvilket som helst programmeringsspråk som støtter utvikling av COM-komponenter, som C++, Visual Basic, etc.
Et av COMs største bidrag til Windows-utviklingsverdenen er bevisstheten om konseptet med skille mellom grensesnitt og implementering. Denne bevisstheten har utvilsomt påvirket måten programmerere bygger dagens systemer på. En utvidelse av dette grunnleggende konseptet er konseptet med ett grensesnitt, flere implementeringer. Dette betyr at under kjøretid kan en applikasjon velge å instansiere et grensesnitt fra en av flere konkrete implementeringer.
Grensesnittdefinisjonsspråk og typebiblioteker
Typebiblioteker inneholder metadata som representerer COM-typer. Imidlertid må disse typene først beskrives ved hjelp av Microsoft Interface Definition Language (MIDL). Dette er vanlig praksis når man utvikler en COM-komponent, for eksempel når man starter med definisjonen av typer som bruker IDL. En IDL-fil er det COM gir som lar utviklere definere objektorienterte klasser, grensesnitt, strukturer, oppregninger og andre brukerdefinerte typer uavhengig av et språk. COM IDL ligner i utseende på C- eller C++-deklarasjoner med tillegg av nøkkelord som "grensesnitt" og "bibliotek" for henholdsvis definisjon av grensesnitt og samlinger av klasser. IDL krever også bruk av parentesattributter før deklarasjoner for å gi tilleggsinformasjon, for eksempel GUID for grensesnitt og forholdet mellom peker- og lengdeparametere til felt.
IDL-filen er kompilert av MIDL-kompilatoren på et par måter for bruk på forskjellige språk. For C/C++ genererer MIDL-kompilatoren en kompilatoruavhengig overskrift som inneholder strukturdefinisjoner som samsvarer med de virtuelle funksjonene til grensesnittdeklarasjonen og en C-fil som inneholder grensesnittdeklarasjons-GUIDer. C++-kildekoden for en proxy -modul kan også genereres av MIDL-kompilatoren. Denne proxyen inneholder stubmetoder for å konvertere COM-anrop til RPC, dette er tillatt av DCOM.
En IDL-fil kan også kompileres av MIDL-kompilatoren til et typebibliotek (.TLB-fil). De binære metadataene i biblioteket er ment å bli behandlet av språkets kompilatorer og kjøretidsmiljøer (VB, Delphi, .NET CLR, etc.). Sluttresultatet av slik TLB-behandling er at det produseres språkspesifikke konstruksjoner som representerer COM-klassen definert i .TLB (og til slutt den som er definert i IDL-kildefilen).
Referansetelling
Det viktigste av alle COM-grensesnitt, dvs. IUnknown (som alle COM-grensesnitt må komme fra), støtter to hovedkonsepter: spørre etter funksjoner (eller grensesnitt som et objekt implementerer) via metode queryInterface(), og administrasjon av objektets livssyklus ved å inkludere AddRef ()og Release (). Funksjonen Referansetelling og spørring gjelder for objekter (ikke for hvert grensesnitt) og må derfor ha en sentralisert implementering.
COM-spesifikasjonene krever en teknikk som kalles referansetelling for å sikre at de ulike objektene er i live så lenge det er klienter som har skaffet seg tilgang til ett eller flere av grensesnittene deres, og omvendt at det samme objektet blir riktig kastet når all kode er present. som bruker objektet er ferdig med det og krever det ikke lenger. Et COM-objekt er ansvarlig for å frigjøre sitt eget minne når referanseantallet er redusert til null.
For utføringen opprettholder et COM-objekt generelt en verdi som brukes som referanse for telling. Når det kalles AddRef ()opp gjennom et av objektets grensesnitt, økes denne verdien. Når kalles Release(), reduseres dette heltall. AddRef ()og Release ()de er de eneste måtene en klient til et COM-objekt kan påvirke livssyklusen på. Den interne verdien forblir et privat medlem av COM-objektet og vil aldri være direkte tilgjengelig.
Instantiering
COM standardiserer prosessen med å instansiere (det vil si å lage) COM-objekter ved å kreve bruk av Fabrikker -klassen . For hvert COM-objekt som ble opprettet, må to tilknyttede parametere eksistere:
- En ID -klasse .
- En fabrikkklasse .
Hver COM-klasse eller CoClass må være tilknyttet en unik klasse- ID (en GUID). Den må også knyttes til sin egen Factory -klasse (som oppnås ved å bruke et sentralisert register). En Factory -klasse er i seg selv et COM-objekt. Det er et objekt som må eksponere grensesnittet IClassFactory eller IClassFactory2 (sistnevnte med støttelisensene). Ansvaret til en slik gjenstand er opprettelsen av andre gjenstander.
En fabrikkklasse er vanligvis inneholdt i den samme kjørbare koden (det vil si kodeserveren) som selve COM-objektet. Når en Factory -klasse kalles for å lage et målobjekt, er dette objektets mål klasse-ID-en som må oppgis. Dette er hvordan Factory -klassen vet hvilken klasse av objektet til forekomst.
En enkelt Factory -objektklasse kan lage objekter av mer enn én klasse. Det vil si at to objekter med forskjellige klasse- IDer kan opprettes av samme Factory -objektklasse. Dette er imidlertid transparent for COM-systemet.
Ved å delegere ansvaret for å lage et objekt til et separat objekt, oppnås et høyere abstraksjonsnivå og utvikleren har mer fleksibilitet.
For at klientapplikasjoner skal skaffe Factory -objektklasser , må COM-servere eksponere dem på riktig måte. En fabrikkklasse eksponeres forskjellig, avhengig av typen serverkode. En server som er basert på DLL-er må eksportere en global funksjon DllGetClassObject (). En server EXE som er basert på Factory -klassen registreres ved kjøretid gjennom Windows API-funksjonen til CoRegisterClassObject ().
Programmering
COM er en binær standard og kan utvikles i et hvilket som helst programmeringsspråk som er i stand til å forstå og implementere dets definerte binære datatyper og grensesnitt.
Kjøretidsbiblioteker (i ekstreme situasjoner, programmerere) er ansvarlige for å komme inn og ut av COM-miljøet, instansiering og referansetelling av COM-objekter, objekter for å spørre versjonsinformasjon, koding for å utnytte avanserte versjoner av objekter.
Søknads- og nettverksgjennomsiktighet
COM-objekter kan instansieres og refereres til i en prosess, på tvers av prosessgrenser i en datamaskin og på tvers av et nettverk ved hjelp av DCOM -teknologi . Å avslutte prosessen og eksterne objekter kan bruke serialisering til å sende metodeanrop og returnere verdier bakover og fremover. Serialiseringen er usynlig for objektet og koden som bruker objektet.
Kritikk
Pumpemelding
Når en STA initialiseres, skaper den et skjult vindu som brukes for meldingsruting mellom leiligheter og prosesser. Meldingskøen skal pumpes regelmessig i dette vinduet. Denne konstruksjonen er kjent som en meldingsbombe. I tidligere versjoner av Windows kan det forårsake krasj i hele systemet. Dette problemet er spesielt ekkelt fordi noen Windows APIer initialiserer COM som en del av applikasjonen, noe som får implementeringsdetaljer til å lekke.
Referansetelling
Referansetelling i COM kan forårsake problemer hvis to eller flere objekter er sirkulært referert. En søknadsdesign må ta hensyn til dette slik at objekter ikke blir foreldreløse.
Objekter kan også la referansetelling være aktiv dersom COM "sink case" er modellen som brukes. Siden objektet som utløser hendelsen trenger en objektreferanse for å reagere på hendelsen, når objektreferansetellingen aldri null.
DLL helvete
Fordi plasseringen av hver komponent er lagret på en systemomfattende plassering (Windows-registret), kan det være at det bare er én versjon av en bestemt komponent installert. Derfor lider COM alvorlig av DLL hell , der to eller flere applikasjoner krever forskjellige versjoner av samme komponent.
Windows XP introduserer en ny modus for COM-objektregistrering: "COM Free Registration". Denne tjenesten gjør det mulig for applikasjoner som må installere COM-objekter å lagre all registerinformasjonen som trengs for COM-registrering i forespørselskatalogen, i stedet for i det globale registret, hvor det strengt tatt kun brukes en enkelt forespørsel. DLL helvete, kan unngås med registerfri COM, den eneste begrensningen er at den krever minst Windows XP eller nyere versjoner av Windows og at den ikke skal brukes for EXE, COM eller serveromfattende systemkomponenter som MDAC , MSXML , DirectX eller Internet Explorer.
Referanser
- Berger, Dan (2004). « COM: En kort introduksjon » . Afrikansk historie på About.com . Hentet 6. februar 2006 .
- Microsoft Corp. (2006). « Komponentobjektmodell » . Arkivert fra originalen 2006-03-18 . Hentet 6. februar 2006 .
- Box, Don (1998). Viktig COM . Addison-Wesley Object Technology Series . ISBN 0-201-63446-5 .
Se også
- Distribuert komponentobjektmodell (DCOM)
- Dynamisk datautveksling (DDE)
- Microsoft .NET (.NET)
- Objektkobling og innebygging (OLE)
- programvarekomponent
- Komponentbasert programvareteknikk
Eksterne lenker
- Microsoft COM-teknologier .
- Hva OLE egentlig handler om av Kraig Brockschmidt. En oversikt over COM og OLE. (På engelsk).
- Component Application Group hos Microsoft Research .
- Mozilla ActiveX Project (på engelsk).
- Introduksjon til Com .
- INFO: Forskjellen mellom OLE-kontroller og ActiveX-kontroller fra Microsoft.