Gränssnittspekare och gränssnitt
En instans av en gränssnittsimplementering är i själva verket en pekare till en matris med pekare till metoder, dvs. en funktionstabell som refererar till en implementering av alla metoder som anges i gränssnittet. Objekt med flera gränssnitt kan ge pekare till mer än en funktionstabell. All kod som har en pekare genom vilken den kan komma åt matrisen kan anropa metoderna i gränssnittet.
Det är obekvämt att tala exakt om den här indirekta avvikelsen, så i stället kallas pekaren till gränssnittsfunktionstabellen som ett annat objekt måste anropa sina metoder bara för en gränssnittspekare. Du kan skapa funktionstabeller manuellt i ett C-program eller nästan automatiskt med hjälp av Visual C++ (eller andra objektorienterade språk som stöder COM).
Med lämpligt kompilatorstöd (som ingår i C och C++) kan en klient anropa en gränssnittsmetod via dess namn, inte dess position i matrisen. Eftersom ett gränssnitt är en typ kan kompilatorn, givet namnen på metoderna, kontrollera typerna av parametrar och returnera värden för varje gränssnittsmetodanrop. Om en klient däremot använder ett positionsbaserat anropsschema är sådan typkontroll inte tillgänglig, inte ens i C eller C++.
Varje gränssnitt är ett oföränderligt kontrakt för en funktionell grupp med metoder. Du refererar till ett gränssnitt vid körning med en globalt unik gränssnittsidentifierare (IID). Detta IID, som är en specifik instans av en globalt unik identifierare (GUID) som stöds av COM, gör det möjligt för en klient att fråga ett objekt exakt om det stöder gränssnittets semantik, utan onödiga omkostnader och utan den förvirring som kan uppstå i ett system från att ha flera versioner av samma gränssnitt med samma namn.
Sammanfattnings nog är det viktigt att förstå vad ett COM-gränssnitt är och inte är:
- Ett COM-gränssnitt är inte detsamma som en C++-klass. Den rena virtuella definitionen har ingen implementering. Om du är C++-programmerare kan du definiera implementeringen av ett gränssnitt som en klass, men detta faller under rubriken implementeringsinformation, som COM inte anger. En instans av ett objekt som implementerar ett gränssnitt måste skapas för att gränssnittet faktiskt ska finnas. Dessutom kan olika objektklasser implementera ett gränssnitt på ett annat sätt men ändå användas omväxlande i binär form, så länge beteendet överensstämmer med gränssnittsdefinitionen.
- Ett COM-gränssnitt är inte ett objekt. Det är helt enkelt en relaterad grupp funktioner och är den binära standard genom vilken klienter och objekt kommunicerar. Så länge det kan ge pekare till gränssnittsmetoder kan objektet implementeras på valfritt språk med valfri intern tillståndsrepresentation.
- COM-gränssnitt är starkt skrivna. Varje gränssnitt har en egen gränssnittsidentifierare (ett GUID), vilket eliminerar risken för duplicering som kan inträffa med andra namngivningsscheman.
- COM-gränssnitt är oföränderliga. Du kan inte definiera en ny version av ett gammalt gränssnitt och ge den samma identifierare. Om du lägger till eller tar bort metoder för ett gränssnitt eller ändrar semantik skapas ett nytt gränssnitt, inte en ny version av ett gammalt gränssnitt. Därför kan ett nytt gränssnitt inte vara i konflikt med ett gammalt gränssnitt. Objekt kan dock ha stöd för flera gränssnitt samtidigt och kan exponera gränssnitt som är efterföljande revisioner av ett gränssnitt, med olika identifierare. Därför är varje gränssnitt ett separat kontrakt, och systemomfattande objekt behöver inte bry sig om huruvida den version av gränssnittet som de anropar är den de förväntar sig. Gränssnitts-ID :t (IID) definierar gränssnittskontraktet explicit och unikt.
Relaterade ämnen