Verwenden systemeigener .NET-COM-Server
Aktualisiert: November 2007
In diesem Abschnitt werden die verfügbaren Optionen für die Verwendung vorhandener COM-Komponenten aus .NET-Anwendungen sowie die Vor- und Nachteile der jeweiligen Ansätze beschrieben. Die generell empfohlene Methode ist C++ Interop.
Verwenden von TLBIMP
Das im Windows Software Development Kit (SDK) enthaltene Type Library Importer-Tool (Tlbimp.exe) ist ein Tool, das eine COM-Typbibliothek als Assembly bereitstellt. Diese Assembly wird als Interop-Assembly bezeichnet. Diese Assembly definiert für jede COM-Schnittstelle in einer gegebenen Typbibliothek verwaltete Äquivalente bzw. Wrapper.
Beim Aufruf von Methoden in der Interop-Assembly wird ein Übergang von verwaltetem zu nicht verwaltetem Code ausgeführt, und die Kontrolle wird an die COM-Komponente übergeben. Ebenso findet beim Rücksprung aus der nicht verwalteten COM-Funktion ein Übergang von nicht verwaltetem Code zu verwaltetem Code statt. Standardmäßig wird COM HRESULT auf Fehler überprüft, und es wird eine Ausnahme ausgelöst, wenn HRESULT nicht die erfolgreiche Ausführung angibt. Die Initialisierung von COM-Komponenten sowie Schnittstellenabfragen werden ebenfalls von der Interop-Assembly ausgeführt und sind daher vor dem aufrufenden Code verborgen.
Interop-Assemblys stellen keinen Ersatz für die von ihnen repräsentierten COM-Komponenten dar. Die nicht verwalteten COM-Funktionen verbleiben in der COM-Komponente. Die Komponente muss daher auf dem Zielcomputer installiert und registriert werden, da andernfalls Aufrufe der Interop-Assembly fehlschlagen.
Die Verwendung von Tlbimp stellt die einfachste Möglichkeit zur Verwendung einer COM-Komponente in verwaltetem Code dar. Sie ist jedoch mit einigen gravierenden Nachteilen verbunden, die sich besonders bei umfangreichen oder komplexen COM-Schnittstellen bemerkbar machen. Es handelt sich dabei um folgende Nachteile:
Tlbimp generiert für jede COM-Schnittstelle in der Typbibliothek verwaltete Schnittstellen. Es gibt keine Möglichkeit, dieses Verhalten zu beeinflussen, sodass die resultierenden Assemblys sehr groß werden können. (Beispielsweise hat die von Tlbimp für Mshtml.dll generierte Interop-Assembly eine Größe von mehr als 8 MB.) Es gibt auch keine Möglichkeit, eine Schnittstelle zu verbergen, die nur für die Benutzung innerhalb der COM-Komponente vorgesehen ist.
Tlbimp unterstützt nur eine begrenzte Anzahl von Datentypen. Üblicherweise werden nicht unterstützte Typen als generischer, nicht typsicherer IntPtr-Typ in die verwaltete Sphäre importiert, was langwierigen und fehleranfälligen Marshallingcode für die Verwendung der Assembly erforderlich macht. In einigen Fällen kann Tlbimp.exe die Member einer Schnittstelle sogar überhaupt nicht bereitstellen.
Tlbimp generiert eine separate Interop-Assembly, die zusammen mit der endgültigen Anwendung bereitgestellt werden muss.
Wenn diese Nachteile kein Problem darstellen, finden Sie unter Gewusst wie: Verwenden von systemeigenen COM-Servern mit TLBIMP ein Beispiel.
Ändern von MSIL
Die Nachteile von Tlbimp können abgemildert werden, indem die Interop-Assembly mit dem MSIL Disassembler-Tool (Ildasm.exe) disassembliert wird und der MSIL-Code bearbeitet wird, um unnötige Schnittstellendefinitionen zu entfernen und Argumenttypen zu ersetzen. Anschließend muss der MSIL-Code mit dem MSIL Assembler-Tool (Ilasm.exe) erneut assembliert werden. Dieser Vorgang ist sehr fehleranfällig und erfordert Wissen zu MSIL, nicht verwalteten Typen und .NET-Typen. Des Weiteren muss dieser Vorgang jedes Mal erneut ausgeführt werden, wenn die COM-Schnittstellen aktualisiert werden.
C++ Interop
Die Nachteile von Tlbimp und der Bearbeitung von MSIL-Code können in Visual C++ vollständig vermieden werden, da Visual C++ im Gegensatz zu Visual Basic und C# COM-Objekte direkt mithilfe der üblichen COM-Mechanismen verwenden kann (z. B. CoCreateInstance und QueryInterface). Dies wird durch die C++ Interop-Features ermöglicht, die bewirken, dass der Compiler automatisch den Code für den Übergang von verwalteten zu nicht verwalteten Funktionen und umgekehrt einfügt.
Mithilfe von C++ Interop können COM-Komponenten ganz normal verwendet oder in C++-Wrapperklassen gekapselt werden. Diese Wrapperklassen werden als benutzerdefinierte, zur Laufzeit aufrufbare Wrapper oder auch CRCWs bezeichnet (Custom Runtime Callable Wrappers). Sie bieten gegenüber der direkten Verwendung von COM im Anwendungscode zwei Vorteile:
Die entstehende Klasse kann von anderen Sprachen als Visual C++ verwendet werden.
Die Details der COM-Schnittstelle können vor dem verwalteten Clientcode verborgen werden. Anstelle von systemeigenen Typen können .NET-Datentypen verwendet werden, und die Details des Datenmarshallings können transparent in der CRCW durchgeführt werden.
Die Verwendung von Visual C++ zum Kapseln von COM-Schnittstellen wird unter Gewusst wie: Verwenden von systemeigenen COM-Servern mit CRCWs veranschaulicht.
Unabhängig davon, ob COM direkt oder mithilfe einer CRCW verwendet wird, müssen alle Argumente gemarshallt werden, die keine einfachen, blitfähigen Argumente sind. Weitere Informationen zum Datenmarshalling finden Sie unter Verwenden von C++-Interop (implizites PInvoke).
Hinweis: |
---|
MFC-Anwendungen müssen als Singlethreadapartment (STA) initialisiert werden. Wenn Sie beim Überschreiben von InitInstance die Funktion CoInitializeEx aufrufen, geben Sie COINIT_APARTMENTTHREADED an (anstelle von COINIT_MULTITHREADED). Weitere Informationen finden Sie in "PRB: MFC Application Stops Responding When You Initialize the Application as a Multithreaded Apartment (828643)" unter https://support.microsoft.com/default.aspx?scid=kb;en-us;828643. |