4 Stimmen

C#/C++ pInvoke-Tipps

Was ist der beste Weg, um ein C++-Programm so zu ändern, dass es mit pInvoke von C#.NET CF verwendet werden kann?

Ich habe eine große C++-Codebasis, die ausgiebig Gebrauch von STL macht. Nämlich Iteratoren, Container-Klassen und Standard-Strings.

Darüber hinaus werden viele leichtgewichtige Klassen als Wert weitergegeben.

Ich möchte eine C#-GUI auf dieser Codebasis für Windows Mobile Touch-Geräte erstellen.

Ist es das wert?

Ich habe es geschafft, einige Beispiele arbeiten mit pInvoke C++-Code von C#.NET aufrufen, aber das Schreiben von Wrappern für jeden Zugriffspunkt und für alle STL-Rückkehrtypen scheint sehr entmutigend und hässlich. Gibt es einen anderen Weg, oder bin ich etwas ausgestopft?

ÜBRIGENS. Managed C++ ist keine Option, da es in keiner Form von .NET CF unterstützt wird.

--edit: Ich habe eine spezielle Frage in Bezug auf pinvoke.

Angenommen, Sie haben eine Funktion, die eine C++-Zeichenkette als Wert zurückgibt

std::string foo () {
   return std::string ("Hi");
}

Ich verstehe, dass seine nicht möglich, diese Funktion von C# mit pinvoke aufrufen, weil es keine Möglichkeit, die STL-Zeichenfolge zu marshall, aber mein Problem ist, dass ich nicht einmal einen Wrapper schreiben kann, ohne ein neues Array zuzuweisen, weil die zurückgegebene std::string nicht auf dem Heap ist.

char* foo2 () {
   return foo().c_str(); //Very bad
   //the returned pointer is released when the std::string falls out of scope.
   //and will be invalid before the caller is able to do anything with it.
}

Mein Problem ist also, wie man foo in ein pInvoke-geeignetes Format verpacken kann, ohne die gesamte Zeichenfolge neu zuordnen zu müssen.

char* foo2 () {
   std::string f = foo();
   char* waste = new char[f.length()+1];
   strcpy (waste, f.c_str());
   return f;
}

Der Gedanke, dass ich das oben genannte für jeden Punkt tun muss, an dem ich einen std::string zurückgeben muss, ist genug, um mich dazu zu bringen, den Versuch aufzugeben, C# zu verwenden.

3voto

Shane Powell Punkte 12660

Ich persönlich würde sagen, dass es sich lohnt, aber ich stimme dem anderen Beitrag zu, dass es nicht einfach ist.

Mögliche Ansätze können sein:

  1. C-Schnittstelle um die C++-Schnittstelle herum und als DLL bereitgestellt.
  2. COM-Objekte (obwohl WM keine COM-Server unterstützt, so dass Sie gezwungen sind, In-Proc-Server zu verwenden, im Grunde eine DLL-COM-Implementierung). Dies würde Ihnen eine mehr OO-Schnittstelle geben.
  3. Hintergrundprozess, der eine Art API offenlegt. Sie können das Modal "CE Services" verwenden oder eine eigene API entwickeln.

Alle sind möglich und haben ihre Vor- und Nachteile. Was auch immer Sie tun, Sie können keine STL-Typen in der Schnittstelle verwenden. Sie haben sich auf einfache Grundtypen beschränkt, die sich leicht zwischen den Prozessen austauschen lassen. Da Sie sprechen über C#, dann COM kann gehen, wie Sie OO-Schnittstelle aussetzen können.

Ich würde empfehlen, die Schnittstelle zwischen den beiden so einfach wie möglich zu halten.

1voto

JasonRShaver Punkte 4324

Was Sie tun wollen, ist gar nicht so einfach. Wenn Sie realmente wollte es zu tun, ist Ihre beste Wette, einige saubere, C-Schnittstellen, die alle der C + + und STL Zeug wickeln und um Strukturen, die von .net zu C schön übergeben kann erstellen. Je nachdem, wie groß die Codebasis ist, die Sie haben, kann das eine sehr schwierige Aufgabe sein.

Entschuldigung.

0voto

Ilya Khaprov Punkte 2538

Vielleicht sollten Sie einen Com-Wrapper schreiben und dann ein .net-Tool verwenden, das automatisch eine c#-Assembly für Sie erstellt?

0voto

Palace Punkte 31

Erstellt SWIG nicht einen C-ähnlichen Wrapper für C++ für Sie? Wie die Übergabe aller Nicht-Grundlagen von komplexem C++? Korrigieren Sie mich, wenn ich falsch bin, weil ich in einer ähnlichen Situation bin, möchte ich eine sehr große und komplexe C++-Api in einer DLL ausgesetzt wickeln..ich brauche, um Mangling und die nicht grundlegenden Datentypen durch das Schreiben eines C-Stil-Wrapper zu vermeiden, um alle Sachen vor Pinvoking, dass und es ist undurchführbar ohne automatisierte Tools angesichts der Größe der api und die Komplexität der Typen und Prototypen freizulegen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X