Standardmäßiges Marshalling für Klassen
Aktualisiert: November 2007
Klassen können nur durch COM-Interop gemarshallt werden und werden immer als Schnittstellen gemarshallt. In einigen Fällen wird die zum Marshallen der Klasse verwendete Schnittstelle als Klassenschnittstelle bezeichnet. Weitere Informationen zum Außerkraftsetzen der Klassenschnittstelle mit einer beliebigen Schnittstelle finden Sie unter Einführung in die Klassenschnittstelle.
Übergeben von Klassen an COM
Wenn eine verwaltete Klasse an COM übergeben wird, umhüllt der Interop-Marshaller die Klasse automatisch mit einem COM-Proxy und übergibt die durch den Proxy erzeugte Klassenschnittstelle an den COM-Methodenaufruf. Der Proxy delegiert die Aufrufe für die Klassenschnittstelle dann zurück an das verwaltete Objekt. Darüber hinaus stellt der Proxy weitere Schnittstellen bereit, die nicht explizit durch die Klasse implementiert werden. Schnittstellen wie IUnknown und IDispatch werden vom Proxy für die Klasse automatisch implementiert.
Übergeben von Klassen an .NET-Code
Co-Klassen werden in COM normalerweise nicht als Methodenargumente verwendet, sondern anstelle der Co-Klasse wird eine Standardschnittstelle übergeben.
Wenn eine Schnittstelle in verwalteten Code übergeben wird, ist der Interop-Marshaller dafür verantwortlich, die Schnittstelle mit dem entsprechenden Wrapper zu umhüllen und den Wrapper an die verwaltete Methode zu übergeben. Unter Umständen ist es schwierig, den zu verwendenden Wrapper festzulegen. Jede Instanz eines COM-Objekts verfügt unabhängig von der Anzahl der Schnittstellen, die das Objekt implementiert, über einen einzelnen, eindeutigen Wrapper. So verfügt beispielsweise ein einzelnes COM-Objekt, das fünf unterschiedliche Schnittstellen implementiert, nur über einen Wrapper. Dieser eine Wrapper macht alle fünf Schnittstellen verfügbar. Wenn zwei Instanzen des COM-Objekts erstellt werden, werden auch zwei Instanzen des Wrappers erstellt.
Damit der Wrapper während seiner gesamten Lebensdauer denselben Typ beibehalten kann, muss der Interop-Marshaller den richtigen Wrapper identifizieren, wenn eine durch das Objekt verfügbar gemachte Schnittstelle erstmals über den Marshaller übergeben wird. Der Marshaller identifiziert das Objekt, indem er eine der durch das Objekt implementierten Schnittstellen betrachtet.
Beispielsweise bestimmt der Marshaller, dass zum Umhüllen der Schnittstelle, die in verwalteten Code übergeben wurde, der Klassenwrapper verwendet wird. Wenn die Schnittstelle erstmals über den Marshaller übergeben wird, überprüft dieser, ob die Schnittstelle von einem bekannten Objekt stammt. Diese Überprüfung erfolgt in zwei Situationen:
Wenn eine Schnittstelle durch ein anderes, an anderer Stelle an COM übergebenes verwaltetes Objekt implementiert wird. Der Marshaller kann durch verwaltete Objekte verfügbar gemachte Schnittstellen problemlos identifizieren und die Schnittstelle dem verwalteten Objekt zuordnen, das die Implementierung bereitstellt. Das verwaltete Objekt wird dann an die Methode übergeben; ein Wrapper ist nicht erforderlich.
Wenn ein bereits umhülltes Objekt die Schnittstelle implementiert. Um festzustellen, ob dies der Fall ist, fragt der Marshaller das Objekt nach der IUnknown-Schnittstelle ab und vergleicht die zurückgegebene Schnittstelle mit den Schnittstellen anderer Objekte, die bereits umhüllt sind. Wenn die Schnittstelle mit der eines anderen Wrappers übereinstimmt, haben die Objekte dieselbe Identität, und der vorhandene Wrapper wird an die Methode übergeben.
Wenn eine Schnittstelle nicht aus einem bekannten Objekt stammt, geht der Marshaller folgendermaßen vor:
Der Marshaller fragt das Objekt nach der IProvideClassInfo2-Schnittstelle ab. Wenn diese Schnittstelle zur Verfügung gestellt wird, verwendet der Marshaller die aus IProvideClassInfo2.GetGUID zurückgegebene CLSID, um die Co-Klasse zu identifizieren, die die Schnittstelle bereitstellt. Mithilfe der CLSID kann der Marshaller den Wrapper über die Registrierung finden, sofern die Assembly zuvor registriert wurde.
Der Marshaller fragt die Schnittstelle nach der IProvideClassInfo-Schnittstelle ab. Wenn diese Schnittstelle zur Verfügung gestellt wird, verwendet der Marshaller die aus IProvideClassInfo.GetClassinfo zurückgegebene ITypeInfo, um die CLSID der Klasse festzulegen, die die Schnittstelle verfügbar macht. Der Marshaller kann die CLSID dazu verwenden, die Metadaten für den Wrapper zu finden.
Wenn der Marshaller die Klasse noch immer nicht identifizieren kann, umhüllt er die Schnittstelle mit einer allgemeinen Wrapperklasse mit der Bezeichnung System.__ComObject.
Siehe auch
Konzepte
Blitfähige und nicht blitfähige Typen