Das Kefk Network Wiki befindet sich im Testbetrieb.
Component Object Model
Aus Kefk.
Das Component Object Model [kəmˈpoʊnənt ˈɑːbdʒɪkt ˈmɑːdl̩] (Abkürzung COM) ist eine von Microsoft entwickelte proprietäre Plattform-Technologie, um unter dem Betriebssystem Windows Interprozesskommunikation und dynamische Objekterzeugung zu ermöglichen. COM-fähige Objekte sind sprachunabhängig und können sowohl DLLs als auch ausführbare Programme sein. Jedes COM-Objekt bietet ein Interface an, welches nach erfolgreicher Instanzierung dazu verwendet werden kann, die angebotenen Funktionen des COM-Objektes einzusetzen. Somit soll COM eine leichte Wiederverwendung von bereits geschriebenem Programmcode, auch über (Windows-)Betriebssystemgrenzen hinweg, möglich machen.
Inhaltsverzeichnis |
Architektur
COM basiert auf dem Client/Server-Prinzip: Unter einem COM-Server versteht man ein Objekt, welches in einer COM-fähigen Programmiersprache erstellt wurde. Der COM-Server bietet die aufrufbaren Funktionen über ein COM-Interface an. Der Client ist das Programm, welches
- möglicherweise eine Instanz des COM-Servers erzeugt und
- die vom COM-Server angebotenen Funktionen benutzt.
Der Client kennt die Funktionen, die vom COM-Server angeboten werden, da diese in den entsprechenden COM-Interfaces deklariert sind.
Damit gewährleistet wird, dass die Instanzierung und darauf folgende Aufrufe des Clients von Serverfunktion auch dann möglich sind, wenn der Client in einer anderen Programmiersprache als der Server programmiert wurde, findet das so genannte Marshalling statt, welches die auszutauschenden Daten in eine sogenannte programmiersprachenunabhängige IDL (Interface Definition Language) umwandelt.
COM-Interface
Ein COM-Interface selbst ist COM-intern ein Zeiger, der auf die so genannte VTable zeigt, eine Tabelle, die wiederum Zeiger auf die Funktionen enthält, die vom COM-Objekt angeboten werden. Ein Interface hat außerdem eine systemweit einmalige Identifikationsnummer, die GUID (Globally Unique Identifier), welche das Interface eindeutig identifiziert. Dadurch können auch mehrere Interfaces mit demselben Namen existieren (aber nicht mit derselben GUID). Es ist möglich, dass ein COM-Server mehrere Interfaces anbietet. Dies ist in bestimmten Situationen unter anderem auch notwendig, um ein Programm erweitern zu können, ohne andere Programme neu kompilieren zu müssen, denn der Compiler kodiert die aus der VTable gelesenen Einsprungadressen der vom Client aufgerufenen Funktionen unter bestimmten Umständen fest. Wird das Interface des Servers später geändert, kann sich die Einsprungadresse ändern, was die Funktionstüchtigkeit des Clients beeinträchtigen würde. Zur Erweiterung der Serverfunktionalität wird also stattdessen ein weiteres Interface implementiert.
Ein Interface sieht in der für COM-Objekte nutzbaren IDL (Interface Definition Language) wie folgt aus (als Beispiel dient das Interface IUnknown):
[
object,
uuid(00000000-0000-0000-C000-000000000046)
]
interface IUnknown {
[restricted]
HRESULT _stdcall QueryInterface([in] GUID* rrid,
[out] void** ppvObj);
[restricted]
unsigned long _stdcall AddRef();
[restricted]
unsigned long _stdcall Release();
}
Jedes Interface muss die Funktionen des hier gezeigten Interfaces IUnknown definieren, da dieses die grundlegenden Funktionen für COM implementiert, u. a. AddRef() und Release() für die Referenzzählung: Ein COM-Objekt lebt nur so lange, wie es Referenzen auf sein Interface gibt. Eine Vererbung der Interfacedefinitionen ist möglich, jedoch nicht die Vererbung der COM-Objekte an sich.
Es ist möglich, beliebig viele Instanzen einer COM-Komponente zu erzeugen. Dazu muss eine so genannte Klassen-Fabrik erzeugt werden. Diese stammt ebenfalls von IUnknown ab und beinhaltet die Implementierung der Funktion CreateInstance().
Da Programmiersprachen wie Visual Basic Script keine Typen kennen, hat Microsoft eine zweite Möglichkeit entwickelt, Funktionen aus COM-Objekten aufzurufen. Für diese Möglichkeit muss das Interface die Funktionen des Interfaces IDispatch definieren. Dies erlaubt es dann dem Programmierer, ein IDispatch zu instanzieren und über dessen Funktion Invoke() die Funktionen des genutzten COM-Objekts abzurufen. Da der Zugriff über das Dispatch-Interface sehr viel langsamer als der Zugriff über ein normales Interface ist, wird oft beides implementiert (Dual Interface), so dass sich der Programmierer bei Programmiersprachen, die Pointer beherrschen, den Weg des Zugriffs auf das COM-Objekt aussuchen kann.
Das Steuern von Anwendungen über COM-Interfaces wird als Automatisierung bezeichnet. Das Interface IDispatch erlaubt hierbei der Client-Anwendung, die Server-Anwendung zu steuern, ohne deren Typenbibliothek zu kennen.
COM-Server
COM-Objekte werden von COM-Servern angeboten. Von diesen gibt es drei Typen.
In-process-Server
Im Falle des In-process-Servers ist das COM-Objekt in einer DLL implementiert (sie tragen unter Windows oft die Dateiendung OCX). Diese DLLs müssen die Funktionen DllGetClassObject(), DllCanUnloadNow(), DllRegisterServer() und DllUnregisterServer() exportieren.
Wird über ein Interface auf ein COM-Objekt zugegriffen, so wird der zugehörige Server (ein Server kann mehrere COM-Objekte anbieten) in den Prozess des Clients geladen. Dies ist der Grund dafür, warum diese Server nur als DLL existieren, denn unter Windows können nur diese in einen Prozess injiziert werden. In-process-Server sind besonders schnell, da der Zugriff auf die Funktionen der COM-Objekte keine Umwege nötig macht (sofern die Zugriffe auf die COM-Objekte nicht thread-überschreitend sind, ist der Marshaler nicht nötig). Jedoch muss jeder Prozess, der ein COM-Objekt nutzen möchte, das in einem In-process-Server implementiert ist, dieses für sich in den Speicher laden, was nicht besonders speicherschonend ist.
Local Server
Local Server sind unter Windows ausführbare Programme, die COM-Objekte implementieren. Bei Zugriff auf ein COM-Objekt wird dieses Programm gestartet (sofern es nicht schon läuft) – dies bedeutet, dass ein Executable vorliegen muss, eine DLL kann hier nicht aufgerufen werden. Zur Kommunikation zwischen Client und Server wird ein abgespecktes RPC-Protokoll (Remote Procedure Call) benutzt. Local Server haben den Vorteil, dass sie nur einmal gestartet werden müssen und dann viele Clients bedienen können, was speicherschonend ist. Die Zugriffe über RPC sind allerdings langsamer.
Remote Server
Befindet sich zwischen Server und Client ein Netzwerk, so kommt DCOM (Distributed COM) zum Einsatz. Der Einsatz von DCOM macht es theoretisch möglich, dass Server und Client auf unterschiedlichen Betriebssystemen laufen.
DCOM benutzt im Gegensatz zum Local Server ein vollständig implementiertes RPC, was die Aufrufe jedoch (auch bei sehr geringer Netzwerkauslastung) deutlich verlangsamt. Die Implementierung vom DCOM unterscheidet sich von der von COM mit Local Server zusätzlich noch durch den vorgeschalteten Protokollstack.
Durch eine Sicherheitslücke in der RPC-Implementation von DCOM wurde die Angriffsweise des bekannten Wurms W32.Blaster möglich.
Apartments
COM-Objekte und Threads werden normalerweise in so genannten Apartments eingebettet. Dabei handelt es sich um transparente Rahmen, welche zur Serialisierung von solchen Methodenaufrufen in Objekten dienen, die nicht threadsicher sind. Wird COM nicht mitgeteilt, dass ein entsprechender Aufruf threadsicher ist, wird COM nur einen Aufruf gleichzeitig an ein Objekt erlauben. Threadsichere Objekte können beliebig viele Aufrufe gleichzeitig ausführen.
Geschieht ein Aufruf im gleichen Apartment zwischen verschiedenen Objekten ist kein Marshalling erforderlich. Wird jedoch ein Interface über Apartmentgrenzen hinweg benutzt, muss ein Marshalling erfolgen. Jeder Thread, welcher COM verwendet, und jedes Objekt, das durch diesen Thread erzeugt wird, wird dem gleichen Apartment zugewiesen. Bei Aufrufen über Prozessgrenzen hinweg liegen die beiden Objekte immer in verschiedenen Apartments.
Es gibt drei Arten von Apartments:
- Single Threaded Apartments (STA) besitzen genau einen Thread und beliebig viele Instanzen von Objekten. Es können beliebig viele STAs existieren. Rufen mehrere Clients eine bestimmte Funktion in einem Server auf, wird jeder Aufruf in einem anderen Apartment erzeugt. Es erfolgt nur ein Aufruf gleichzeitig an das aufzurufende Objekt. STAs kommen normalerweise zum Einsatz, wenn man nicht explizit mitteilt, dass Aufrufe threadsicher sind. Die restlichen Aufrufe warten in einer Warteschlage.
- Multi Threaded Apartments (MTA) besitzen beliebig viele Threads. Es gibt in einem Prozess allerdings maximal ein MTA. Dadurch können von mehreren Clients gleichzeitig Aufrufe an das gleiche Objekt erfolgen.
- Natural Threaded Apartments (NTA) bieten die Möglichkeit, einen Thread, welcher in Apartment A läuft, kurzzeitig in Apartment B auszuführen, um beispielsweise aus Performancegründen das Marshalling zu überspringen.
Funktionalität
Durch den Einsatz von COM erhält ein Programmierer die Möglichkeiten
- sprachunabhängig,
- versionsunabhängig,
- plattformunabhängig,
- objektorientiert,
- ortsunabhängig
zu programmieren. Viele der Funktionen des „Windows Platform SDKs“ sind über COM zugänglich. COM ist die Basis, auf der OLE-Automation und ActiveX realisiert sind. Mit der Einführung des .NET-Frameworks verfolgt Microsoft allerdings die Strategie, COM unter Windows durch ebendieses Framework abzulösen. Im Folgenden werden die einzelnen Punkte der Aufzählung genauer erläutert.
Sprachunabhängigkeit
Das wichtigste Argument für COM ist sicherlich die Sprachunabhängigkeit. COM unterstützt den so genannten Binärstandard. Dadurch kann ein Programmierer ein Programm als COM-Komponente, in einer objektorientierten Programmiersprache compilieren. Die erzeugte Binärdatei stellt einerseits die implementierten Funktionen zur Verfügung und andererseits ein Interface, welches diese Funktionen aufzeigt. Mit Hilfe des Interfaces ist es möglich, von anderen Programmen aus die Funktionen zu verwenden. Dabei wird mit Konzepten aus dem Bereich Verteilte Systeme gearbeitet.
Versionsunabhängigkeit
Ein weiterer wichtiger Vorteil beim Einsatz von COM ist es, dass man die Verwaltung von neuen Softwarefeatures einfach in eine bestehende Anwendung integrieren kann. Oftmals kann es Probleme geben, wenn man herstellerneutrale oder herstellerübergreifende Softwarekomponenten mit weiteren Funktionen ausstattet. Dadurch kann zwar die eigene Software erweitert werden, jedoch besteht die Gefahr, dass andere Software welche ebenfalls die herstellerübergreifenden Komponenten verwendet, nicht mehr funktionsfähig bleibt.
COM bietet eine robuste Möglichkeit an, um eine Softwarekomponente mit neuen Funktionen zu erweitern. Dies wird dadurch ermöglicht, dass mehrere Interfaces in einer Header-Datei zusammengefasst werden können. Der folgende C++-Programmcode verdeutlicht dies:
//
// Interface mathematik.h
//
class IStandardMathFunctions : public IUnknown
{
public:
STDMETHOD(Addieren)(long, long, long*)
STDMETHOD(Subtrahieren)(long, long, long*)
};
class IAdvancedMathFunctions : public IUnknown
{
public:
STDMETHOD(Fibonacci)(short, long*)
}
Dieser Header namens mathematik.h enthält zwei Interfaces. Das erste Interface könnte beispielsweise die herstellerübergreifenden Funktionen anbieten, die von verschiedenen Programmen verwendet werden. Durch das zweite Interface IAdvancedMathFunctions wird diese Softwarekomponente erweitert. Weitere Interfaces können jederzeit hinzugefügt werden. Die alten Interfaces und darin enthaltenen Funktionen gehen dabei nicht verloren. Das Hinzufügen neuer Interfaces statt des Veränderns derselben ist so die von Microsoft angedachte Form, Softwarekomponenten zu erweitern, da so keine Inkonsistenzen entstehen.
Plattformunabhängigkeit
x64-Applikationen können dank Marshalling auf 32bittige COM-Server zugreifen (und umgekehrt). Der COM-Server muss dann in einem eigenen Prozess laufen und seine Objekte können demnach nicht mit der INPROC_SERVER Variante instanziiert werden.
Objektorientierung
Beim Einsatz von COM wird objektorientiert gearbeitet.
Ortsunabhängigkeit
COM ist ortsunabhängig, d. h. dass die einzelnen COM-Komponenten an einer zentralen Stelle (Registry) angemeldet werden und so der Zugriff auf die Komponenten unabhängig von ihrem eigentlichen Ort erfolgen kann.
Siehe auch: Ortstransparenz
Siehe auch
- Object Linking and Embedding
- .NET-Framework
- Objektorientierte Programmierung
- Verteilte Systeme
- Komponente (Software)
Literatur
- Olaf Zwintzscher: Software-Komponenten im Überblick. Einführung, Klassifizierung & Vergleich von JavaBeans, EJB, COM+, Net, CORBA, UML 2. W3L, Herdecke 2005, ISBN 3-937137-60-2
Weblinks
| Dieses Dokument entstammt in seiner ersten oder einer späteren Version der deutschsprachigen Wikipedia. Es ist dort zu finden unter dem Stichwort Component_Object_Model, die Liste der bisherigen Autoren befindet sich in der Versionsliste; die Originalfassung kann dort auch bearbeitet werden. Alle Texte der Wikipedia und ihre Derivate stehen unter der GNU-Lizenz für freie Dokumentation. |
