Wie im Titel angegeben, möchte ich, dass meine alte C ++ - Bibliothek in Managed .NET funktioniert. Ich denke an zwei Möglichkeiten:
1) Ich könnte versuchen, die Bibliothek mit / clr zu kompilieren und "It Just Works" -Ansatz zu versuchen.
2) Ich könnte einen verwalteten Wrapper in die nicht verwaltete Bibliothek schreiben.
Zuerst möchte ich, dass meine Bibliothek SCHNELL arbeitet, wie es in einer nicht verwalteten Umgebung war. Daher bin ich mir nicht sicher, ob der erste Ansatz zu einer starken Leistungsminderung führen wird. Allerdings scheint es schneller zu implementieren (kein richtiges Wort :-)) (vorausgesetzt, es wird für mich funktionieren).
Andererseits denke ich an einige Probleme, die während des Schreibens eines Wrappers auftreten könnten (zB wie man eine STL-Sammlung umschließt ( vector
zum Beispiel)?) Ich denke daran, einen Wrapper zu schreiben, der sich im selben Projekt befindet wie der unmanaged C ++ residiert - ist das ein vernünftiger Ansatz (zB MyUnmanagedClass
und MyManagedClass
im selben Projekt, der zweite den anderen umschließt)?
Was würden Sie in diesem Problem vorschlagen? Welche Lösung wird mir eine bessere Leistung des resultierenden Codes geben?
Vielen Dank im Voraus für Anregungen und Hinweise!
Prost
Vergessen Sie zuallererst Managed C ++. Verwenden Sie C ++ / CLI.
Der Unterschied ist, dass Managed C ++ der erste Versuch von Microsoft war, C ++ so zu erweitern, dass es mit .NET funktionierte, und ehrlich gesagt, es war alles andere als schrecklich.
Also haben sie das aufgegeben und stattdessen C ++ / CLI entworfen, was viel besser funktioniert.
Zweitens sollte gültiger C ++ - Code einfach funktionieren , wenn Sie ihn als C ++ / CLI kompilieren, also scheint das der offensichtliche Weg dafür zu sein.
Um Ihre C ++ - Typen für .NET-Assemblies verfügbar zu machen, müssen Sie natürlich einige Wrapper schreiben. Für STL-Typen sollten Sie sich die STL / CLR Bibliothek von Microsoft ansehen.
Aber fügen Sie einfach den / cli-Schalter hinzu, kompilieren Sie Ihren Code als C ++ / CLI und fügen Sie dann die gewünschten Wrapper hinzu. Es gibt keinen Grund, warum dein Code magisch langsamer werden würde oder so.
So wie ich es mache ist
Erstellen Sie eine normale nicht verwaltete .lib. Stellen Sie sicher, dass Sie als DLL eine Verbindung zur Standardlaufzeit herstellen (erforderlich, wenn sich die .lib in einer Assembly befindet)
Erstellen Sie eine C ++ / CLI-Assembly.
Fügen Sie die .lib dem Link wie der Assembly hinzu
Erstellen Sie eine verwaltete Schnittstelle
Minimieren Sie die Granularität von Anrufen über Managed / Unmanaged. Das bedeutet, dass Sie lieber große Datenblöcke (wie eine Datenstruktur) erhalten, anstatt von der verwalteten Seite eine Schnittstelle zu einer nicht verwalteten Datenstruktur zu verwenden. Dies liegt daran, dass Anrufe über die Grenze hinweg langsam sind.
Dinge wie ein std :: vector müssen manuell in System.Collections eingepackt werden - aber "es funktioniert einfach" ist gut für eingebaute Typen und sogar Funktionszeiger.
Andere Fehler. Callbacks müssen Standard sein, um in einen Delegaten umgewandelt zu werden, und Delgates, die an nicht verwaltete Callbacks gesendet werden, enthalten keinen Verweis (also, arrangieren, einen Verweis irgendwo anders zu halten oder abstürzen, wenn das Objekt GC'd ist).
Wenn Sie viele nicht verwaltete Funktionen haben, sollten Sie SWIG verwenden. Es schreibt den gesamten Wrapper- und Interop-Code für Sie und hat SWIG-Interface-Dateien, die std :: vector, std :: string, Windows-Typen usw. unterstützen.
Ich habe ein vollständiges Beispiel, das nicht verwaltete C ++ - DLL-Funktionen offenlegt, wenn Sie daran interessiert sind.