Inter-Object Kommunikation
COM ist so konzipiert, dass Clients transparent mit Objekten kommunizieren können, unabhängig davon, wo diese Objekte ausgeführt werden – im selben Prozess, auf demselben Computer oder auf einem anderen Computer. Dies stellt ein einzelnes Programmiermodell für alle Objekttypen und sowohl für Objektclients als auch für Objektserver bereit.
Aus Sicht eines Clients wird auf alle Objekte über Schnittstellenzeiger zugegriffen. Ein Zeiger muss in Bearbeitung sein. Tatsächlich erreicht jeder Aufruf einer Schnittstellenfunktion immer zuerst einen Teil des prozessinternen Codes. Wenn sich das Objekt in Bearbeitung befindet, erreicht es der Aufruf direkt, ohne dass der Systeminfrastrukturcode dazwischen kommt. Wenn das Objekt out-of-process ist, erreicht der Aufruf zuerst ein sogenanntes "Proxy"-Objekt, das entweder von COM oder vom -Objekt bereitgestellt wird (wenn der Implementor dies wünscht). Die Proxypakete rufen Parameter (einschließlich aller Schnittstellenzeiger) auf und generieren den entsprechenden Remoteprozeduraufruf (oder einen anderen Kommunikationsmechanismus im Fall benutzerdefinierter generierter Proxys) an den anderen Prozess oder den anderen Computer, auf dem sich die Objektimplementierung befindet. Dieser Prozess von Verpackungszeigern für die Übertragung über Prozessgrenzen hinweg wird als Marshalling bezeichnet.
Aus Der Sicht eines Servers erfolgen alle Aufrufe der Schnittstellenfunktionen eines Objekts über einen Zeiger auf diese Schnittstelle. Auch hier weist ein Zeiger nur in einem einzelnen Prozess Kontext auf, und der Aufrufer muss immer ein Teil des prozessinternen Codes sein. Wenn das Objekt in Bearbeitung ist, ist der Aufrufer der Client selbst. Andernfalls ist der Aufrufer ein "Stub"-Objekt, das entweder von COM oder vom Objekt selbst bereitgestellt wird. Der Stub empfängt den Remoteprozeduraufruf (oder einen anderen Kommunikationsmechanismus im Fall von benutzerdefinierten generierten Proxys) vom "Proxy" im Clientprozess, hebt die Parameter auf und ruft die entsprechende Schnittstelle für das Serverobjekt auf. Aus Sicht von Clients und Servern kommunizieren sie immer direkt mit einem anderen prozessinternen Code.
COM stellt eine Implementierung des Marshallings bereit, die als Standardmarsing bezeichnet wird. Diese Implementierung funktioniert für die meisten Objekte sehr gut und reduziert die Programmieranforderungen erheblich, sodass der Marshallingprozess effektiv transparent wird.
Die klare Trennung der Schnittstelle von der Implementierung der Prozesstransparenz von COM kann jedoch in einigen Situationen in die Quere kommen. Der Entwurf einer Schnittstelle, die sich aus Sicht des Clients auf ihre Funktion konzentriert, kann manchmal zu Entwurfsentscheidungen führen, die mit einer effizienten Implementierung dieser Schnittstelle in einem Netzwerk in Konflikt stehen. In solchen Fällen ist nicht reine Prozesstransparenz gefragt, sondern "Prozesstransparenz, es sei denn, Sie müssen sich darum kümmern.". COM bietet diese Funktion, indem es einem Objektimplementierungsor erlaubt, benutzerdefiniertes Marshalling (auch als IMarshal-Marshalling bezeichnet) zu unterstützen. Das Standardmäßige Marshalling ist tatsächlich ein instance des benutzerdefinierten Marshallings. Es ist die Standardimplementierung, die verwendet wird, wenn ein Objekt kein benutzerdefiniertes Marshalling erfordert.
Sie können benutzerdefiniertes Marshalling implementieren, damit ein Objekt andere Aktionen ausführen kann, wenn es in einem Netzwerk verwendet wird, als es unter lokalem Zugriff verwendet wird und für den Client vollständig transparent ist. Diese Architektur ermöglicht es, Client-/Objektschnittstellen ohne Berücksichtigung von Netzwerkleistungsproblemen zu entwerfen und später Probleme mit der Netzwerkleistung zu beheben, ohne den etablierten Entwurf zu stören.
COM gibt nicht an, wie Komponenten strukturiert sind. Es gibt an, wie sie interagieren. COM überlässt die Bedenken bezüglich der internen Struktur einer Komponente Programmiersprachen und Entwicklungsumgebungen. Umgekehrt haben Programmierumgebungen keine festgelegten Standards für die Arbeit mit Objekten außerhalb der unmittelbaren Anwendung. Microsoft Visual C++ funktioniert beispielsweise sehr gut für die Bearbeitung von Objekten innerhalb einer Anwendung, unterstützt jedoch nicht die Arbeit mit Objekten außerhalb der Anwendung. Im Allgemeinen sind in dieser Hinsicht alle anderen Programmiersprachen gleich. Um netzwerkweite Interoperabilität zu gewährleisten, greift COM über sprachunabhängige Schnittstellen daher dort auf, wo Programmiersprachen weglassen.
Die doppelte Dereferenzierung der vtbl-Struktur bedeutet, dass die Zeiger in der Tabelle der Funktionszeiger nicht direkt auf die reale Implementierung im realen Objekt verweisen müssen. Dies ist das Herzstück der Prozesstransparenz.
Bei Prozessinternen Servern, bei denen das Objekt direkt in den Clientprozess geladen wird, verweisen die Funktionszeiger in der Tabelle direkt auf die tatsächliche Implementierung. In diesem Fall überträgt ein Funktionsaufruf vom Client an eine Schnittstellenmethode die Ausführungssteuerung direkt an die -Methode. Dies kann jedoch nicht für lokale, geschweige denn Remoteobjekte funktionieren, da Zeiger auf den Arbeitsspeicher nicht zwischen Prozessen gemeinsam genutzt werden können. Dennoch muss der Client Schnittstellenmethoden aufrufen können, als ob er die eigentliche Implementierung aufrufe. Daher überträgt der Client die Steuerung einheitlich an eine Methode in einem Objekt, indem er den Aufruf vornimmt.
Ein Client ruft immer Schnittstellenmethoden in einem prozessinternen Objekt auf. Wenn das tatsächliche Objekt lokal oder remote ist, wird der Aufruf eines Proxyobjekts ausgeführt, das dann einen Remoteprozeduraufruf an das eigentliche Objekt sendet.
Welche Methode wird also tatsächlich ausgeführt? Die Antwort lautet, dass bei jedem Aufruf einer Out-of-Process-Schnittstelle jede Schnittstellenmethode von einem Proxyobjekt implementiert wird. Das Proxyobjekt ist immer ein prozessinternes Objekt, das im Namen des aufgerufenen Objekts handelt. Dieses Proxyobjekt weiß, dass das eigentliche Objekt auf einem lokalen oder Remoteserver ausgeführt wird.
Das Proxyobjekt packt die Funktionsparameter in einigen Datenpaketen und generiert einen RPC-Aufruf des lokalen oder Remoteobjekts. Dieses Paket wird von einem Stubobjekt im Prozess des Servers auf dem lokalen oder einem Remotecomputer abgerufen, das die Parameter entpackt und die tatsächliche Implementierung der Methode aufruft. Wenn diese Funktion zurückgibt, packt der Stub alle out-Parameter und den Rückgabewert und sendet ihn zurück an den Proxy, der sie entpackt und an den ursprünglichen Client zurückgibt.
Daher kommunizieren Client und Server immer miteinander, als ob alles in Bearbeitung wäre. Alle Aufrufe vom Client und alle Aufrufe an den Server sind irgendwann in Bearbeitung. Da die vtbl-Struktur es einem Agent wie COM jedoch ermöglicht, alle Funktionsaufrufe und alle Rückgaben von Funktionen abzufangen, kann dieser Agent diese Aufrufe bei Bedarf an einen RPC-Aufruf umleiten. Obwohl In-Process-Aufrufe schneller sind als Out-of-Process-Aufrufe, sind die Prozessunterschiede für Client und Server vollständig transparent.
Weitere Informationen finden Sie in den folgenden Themen:
Zugehörige Themen