A
Artchi schrieb:
Wieviel spielt denn Performance eine Rolle?
Ich möchte schon gerne das UI auf der einen und das Model auf der anderen Seite haben können, oder die Implementierung einer Skriptfunktion auf der einen und das Skript auf der anderen. Einen Webservice oder Marshaling über Pipes kommt mir da suboptimal vor. Außerdem besteht mein Problem, wie hustbaer richtig erkannt hat, hauptsächlich in der möglichst automatischen Generierung der Interface-Definitionen in mehreren Sprachen. Das wird auch nicht leichter, wenn ich jetzt einen lokalen Webservice statt COM verwende.
Über CORBA weiß ich leider nichts; wenn das mein Problem löst, könntest du mir mehr darüber sagen wie?
hustbaer schrieb:
Es läuft also darauf hinaus dass du die Interface-Definitionen 1x schreiben willst, und daraus dann die anderen nötigen Files generieren.
Genau. Ich habe mit der oben beschriebenen Technik jetzt ein Projekt umgesetzt, das mittlerweile gut läuft, aber die parallele Wartung der Interfaces war a) nervig und b) eine lästige Fehlerquelle, die schon zahlreiche Stunden gekostet hat, z.B., weil das Marshaling manchmal unerwartetes Standardverhalten hat, oder weil ich eine Methode vergessen habe einzufügen. Unter Mono/Linux gab es noch lustigere Artefakte. (Mono/Windows habe ich aufgegeben, nachdem ich gemerkt hatte, daß Mono das Exception-Handling in C++ kaputtmacht, indem es einen kaputten SEH-Filter registriert.) Das würde ich mir in Zukunft gerne ersparen, und noch wichtiger: wenn jemand anderes an einem solchen Projekt arbeitet, der diese Fehler noch nicht gemacht hat, braucht er nicht auch nochmal auf die Nase fallen.
hustbaer schrieb:
Die Frage ist nur noch: in welchem Format schreibst du die Interface-Definitionen?
Die "Pseudo-C# als Interfacedefinition" Variante würde mir nicht so gefallen, weil verwirrend. Die Pseudo-C# Klassen sehen dabei dann ja so aus als wären sie der verwendete Source-Code, sind es aber nicht. Hmmm...
Ja, das stimmt. Der Vorteil wäre, daß ich sie in Visual Studio schreiben könnte, was sehr bequem ist, aber der Nachteil, wie du sagst, daß ich dann eine Pseudoassembly habe, die gar nicht zur Laufzeit benötigt wird.
hustbaer schrieb:
Ich würde mal gucken ob es fertige MIDL Parser (idealerweise in C#) gibt die du als Basis verwenden kannst.
Hmjagut, nur ist IDL praktisch genau so verbose wie C++, vielleicht noch ein bißchen schlimmer
hustbaer schrieb:
Oder, andere Idee: Guck dir mal die von der MS Toolchain erzeugten COM-Interop-Assemblies an.
Habe ich mal gemacht. Ich könnte ja, wie im Eingangspost skizziert, MIDL nehmen, um einen C++-Header und via TLBIMP eine Typbibliothek für .NET zu bekommen. Der Reflector sagt mir, daß solche Interop-Assemblies abhängigkeitsfrei ist; ich darf nur nicht die Compiler-Magic zum Erzeugen eines COM-Objekts verwenden, denn der Compiler generiert dafür einen Aufruf von Activator.CreateInstance() , und das wird von Mono nicht implementiert. Möglicherweise kann ich die also in Mono direkt verwenden.
Die von MIDL erzeugten Header sind halt nicht so hübsch, u.a., weil ich auf die helper methods verzichten muß und die auch nicht mit einem einfachen Postprocessing-Schritt hinzufügen kann
hustbaer schrieb:
und weil C# keine Interface-Vererbung unterstützt, so daß man die Methoden des Basisinterfaces neudefinieren muß.
Huch?
Siehe z.B. hier und hier. In C# besagt "interface inheritance" lediglich, daß du von Interface IDerived zu Interface IBase casten kannst. In COM sagt "interface inheritance" darüber hinaus, daß die VMT von IDerived zuerst die Einträge von IBase , dann seine eigenen Einträge enthält, d.h. jede IDerived -Referenz ist auch ohne Typecast eine IBase -Referenz. Und zumindest in meinem Ansatz führte das dazu, daß ich in C# die Funktionen von IBase in IDerived wiederholen mußte, wenn ich ein kompatibles VMT-Layout bekommen wollte.
Wenn das nicht so wäre, könnte ich ja auch den umgekehrten Weg gehen, also: eine Assembly voller Interfaces in C# als ComVisible definieren, irgendwie eine IDL rausziehen, mit MIDL einen C++-Header erstellen. Das wäre dann etwas bequemer, als selbst IDL zu schreiben. Aber so muß ich selbst Duplikate der geerbten Funktionen schreiben, um "interface inheritance" à la COM zu simulieren. Wenn ich aber eine C++-Typbibliothek nach .NET importiere, generiert TLBIMP diese Duplikate automatisch für mich.
Danke jedenfalls für eure Beschäftigung mit dem Thema, das hat mir schon viel geholfen.