2009-05-18 16 views
3

Was ist der beste Weg zur Änderung eines C++ - Programms mit pInvoke von C# .NET CF verwendet werden?C#/C++ pInvoke Tipps

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

Obendrein werden viele leichte Klassen wertmäßig weitergegeben.

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

Ist es das wert?

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

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

--edit: Ich habe eine spezifische Frage in Bezug auf Pinvoke.

Angenommen, Sie eine C++ Zeichenfolge nach Wert eine Funktion hatten

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

Ich verstehe, dass es nicht möglich, diese Funktion von C# pinvoke verwenden zu nennen, weil es keine Möglichkeit, marshall der STL-String ist, 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. 
} 

Also mein Problem ist, wie foo in ein pinvoke geeignetes Format wickeln, ohne dass die gesamte Zeichenfolge neu zuordnen.

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

Der Gedanke für jeden Punkt der oben tun, an das ich brauche eine std :: string zurückzukehren ist genug, um mich versuchen, geben zu bilden C# zu verwenden.

Antwort

3

Ich würde persönlich sagen, dass es das wert ist, 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++ und als DLL ausgesetzt.
  2. COM-Objekte (altho WM unterstützt keine COM-Server, so dass Sie gezwungen sind, proc-Server zu verwenden, im Grunde eine DLL COM-Implementierung). Dies würde Ihnen eine mehr OO-Schnittstelle geben.
  3. Hintergrund Prozess ausgesetzt eine Art von API. Sie könnten das Modular "CE-Dienste" herunterfahren oder eine eigene API entwickeln.

Alle sind möglich und haben dort Vor- und Nachteile. Was auch immer Sie tun, Sie können keine STL-Typen in der Schnittstelle verwenden. Sie haben sich auf einfache Grundtypen reduziert, die sich einfach zwischen den Prozessen verteilen lassen. Da Sie über C# sprechen, kann COM gehen, da Sie OO-Schnittstelle verfügbar machen können.

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

+0

Danke für die Tipps, obwohl ich nicht sicher bin, welche Option 3 bedeutet. Ich stimme zu, dass meine Schnittstelle zu breit war und ich die Brücke zwischen C# und C++ so klein wie möglich machen sollte. Derzeit werden sogar Iteratorreferenzen zurückgegeben, die jedes Mal, wenn sie sich selbst inkrementieren oder dereferenzieren, einen Pinvoke-Aufruf erfordern ... eek. – Akusete

+0

Option 3: Sie erstellen eine Anwendung (exe), die im Hintergrund ausgeführt wird (sie kann entweder die gesamte Zeit ausführen oder vom GUI-Frontend gestartet und gestoppt werden) und kommuniziert mit Ihrer Front-End-Anwendung (GUI) über eine API Sie machen es wie Shared Memory oder Message Queues oder was auch immer Sie mögen. Sortieren Sie wie Win32-Dienste. Ihre Hintergrundanwendung würde normalerweise in einer Art von Ereignisschleife Befehle empfangen und sie verarbeiten. –

0

vielleicht sollten Sie einen com wrapper schreiben und dann .net tool verwenden, das automatisch C# assembly für Sie erstellt?

+0

Ich glaube nicht, dass es ein COM-Subsystem in WindowsMobile ... – JasonRShaver

+0

COM gibt es in Windows Mobile –

+0

Es ist da, aber COM Interop in der CF ist * nicht * einfach überhaupt. – ctacke

1

Was Sie wollen, ist gar nicht so einfach. Wenn Sie wirklich wollte es tun, ist Ihre beste Wette, um einige saubere, C-Schnittstellen zu erstellen, die alle C++ und STL-Zeug wickeln und Strukturen herumreichen, die von .net zu C schön übergeben können. Abhängig davon, wie groß eine Codebasis ist, kann dies eine sehr schwierige Aufgabe sein.

Entschuldigung.

+0

Danke für den Rat, ich nahm an, dass dies der Fall war, aber ich wollte sicher sein, bevor ich den Weg hinunter ging. – Akusete

0

erstellt nicht SWIG einen C-style Wrapper für C++ für Sie? Wie alle Nicht-Grundlagen von komplexem C++? Korrigieren Sie mich, wenn ich falsch liege, weil ich in einer ähnlichen Situation bin, möchte ich eine sehr große und komplexe C++ - API in einer DLL offen gelegt. Ich muss Mangling und die nicht-grundlegenden Datentypen durch Schreiben eines C-Stils vermeiden Wrapper, um alle Sachen vor dem Pinvoking zu enthüllen und es ist ohne automatisierte Tools angesichts der Größe der API und der Komplexität der Typen und Prototypen unmöglich.