27 Stimmen

Schnelles C++ Programm, C# GUI, möglich?

Ich bin dabei, eine Anwendung zu entwickeln, die Daten von einer Zeilenkamera mit etwa 2000 Zeilen (Bildern) pro Sekunde verarbeitet. Für diese Echtzeitanwendung halte ich C/C++ für den richtigen Weg. (Ich bin der Meinung, und andere werden mir zustimmen, dass verwalteter Code für diese Aufgabe einfach nicht geeignet ist).

Ich habe jedoch Folgendes getan sehr kleine MFC oder eine andere C++-GUI. Ich bin wirklich immer zu tun C # GUIs sehr gut, aber.

Daher erscheint es mir natürlich, den datenintensiven Code in C/C++ und die grafische Benutzeroberfläche in C# zu schreiben. Die GUI wird für die Einrichtung/Kalibrierung/Online-Überwachung verwendet (und möglicherweise für die Ausgabe von Daten über UDP, weil das in C# einfacher ist.

Daher möchte ich zunächst einmal wissen, ob jemand der Meinung ist, dass dies der richtige Weg wäre. Auf der Grundlage meiner Programmiererfahrung (gut in Low-Level-C-Algorithmen und High-Level-C# GUI-Design), es fühlt sich einfach richtig.

Zweitens bin ich mir nicht sicher, wie ich es am besten anstellen soll. Ich warf gerade zusammen eine Lösung in VS2005, die einige (extern "C") DLL-Funktionen von einer C#-Anwendung aufruft. Und um sicherzustellen, dass ich es tun konnte, schrieb ich auf einige globale Variablen in der DLL, und lesen Sie aus ihnen:

test.h

int globaldata;
extern "C" __declspec(dllexport) void set(int);
extern "C" __declspec(dllexport) int  get();

test.cpp

extern int data=0;
__declspec(dllexport) void set(int num) {
    data = num;
}

__declspec(dllexport) int get() {
    return data;
}

test.cs

[DllImport("test")]
private static extern void set(int num);

[DllImport("test")]
private static extern int get();

Aufruf von get() y set() richtig funktionieren ( get() gibt die Zahl zurück, die ich an set() ).

Ich weiß, dass man auch eine C++-Klasse exportieren kann, aber muss sie auch verwaltet werden? Wie funktioniert das? Gehe ich das richtig an?

Vielen Dank für Ihre Hilfe!

`** EDIT `**

Zuallererst, DANKESCHÖN für Ihre fantastischen Antworten bis jetzt! Ich bin immer unglaublich beeindruckt von Stack Overflow...

Ich denke, ich hätte nicht unbedingt auf die reine Geschwindigkeit eingehen sollen (diese kann in Prototypen und Benchmarks gemessen werden). Eine Sache, die mir mehr Sorgen bereitet, ist das nicht-deterministische Verhalten des Garbage Collectors. Diese Anwendung würde no eine Verzögerung von 500 ms bei der Durchführung der Müllabfuhr tolerieren.

Ich bin alles für die Codierung und versuchen dies in reinen C#, aber wenn ich vor der Zeit wissen, dass die GC und andere nicht-deterministische .NET Verhalten (?) ein Problem verursachen, ich denke, meine Zeit wäre besser verbracht Codierung es in C/C++ und herauszufinden, die beste C#-Schnittstelle.

32voto

17voto

Meiner Meinung nach ist Ihre Lösung gut:

  1. Auch wenn C# schnell ist, kann es nie mit einem gut geschriebenen unmanaged C/C++ konkurrieren, ich habe selbst leistungsstarke Anwendungen gemacht, die dies über die winzigen Beispiele hinaus beweisen, die Leute immer posten, wenn jemand diese Art von Aussagen postet
  2. MFC oder ATL UI-Programmierung ist umständlich und langsam, C # ist der Weg zu gehen hier, ich werde NIE tun MFC / ATL UI-Programmierung jemals wieder, es sei denn, gezwungen zu

Ihre Lösung, falls Sie es noch nicht herausgefunden haben, heißt "Mixed Mode", was im Grunde bedeutet, dass Sie Managed (C#) und Unmanaged (C/C++) Code in den gleichen Projekten zu kombinieren, ist es oft ein bisschen Ärger, um die VS-Projekt up-and-running (LNK2020 Fehler..argh..), aber wenn Sie die richtigen Einstellungen zu finden, sollte es einfach gut funktionieren.

Der einzige Nachteil ist, dass Mixed-Mode-Assemblies in Full Trust ausgeführt werden müssen, wenn das in Ordnung ist, dann wissen Sie, was zu tun ist.

Eine andere Sache, die Sie sich vielleicht ansehen sollten, ist ein Open-Source-Projekt namens SWIG . SWIG nimmt Ihren C/C++-Code und erstellt daraus eine .NET-Assembly. Ich habe es selbst in meinem TM++ Open-Source-Projekt. Hier finden Sie weitere Informationen über SWIG http://www.swig.org/ .

6voto

Matthieu Punkte 2683

Für Echtzeitanwendungen: Ich empfehle C++, Sie sind flexibler bei der Speicherverwaltung, schneller und sogar plattformübergreifend, je nachdem, welches Framework verwendet wird...!

Zum Thema Framework und GUI empfehle ich Ihnen einen Blick auf Qt . Qt ist ein großartiges Framework für die Entwicklung von C++-Software.

Ich glaube, das ist die Lösung für Ihr Problem!

5voto

Niki Punkte 15426

Mein Unternehmen macht etwas ganz Ähnliches, allerdings mit CCD-Kameras anstelle von Zeilenkameras. Wir verwenden C# für die grafische Benutzeroberfläche, die Netzwerkkommunikation und das "Klempnerhandwerk" auf hoher Ebene und C++/CLI für die Algorithmen auf niedriger Ebene. Das funktioniert recht gut. Sie werden nie in der Lage sein, ein echtes Echtzeitsystem mit garantierten maximalen Antwortzeiten unter Windows zu schreiben, aber meiner Erfahrung nach wird die GC hier das geringste Problem sein. Zum einen läuft die GC nur, wenn Sie Speicher zuweisen; das gilt auch für malloc/new in C/C++, und die brauchen auch Zeit (denken Sie an Speicherfragmentierung). Die Messungen, die wir durchgeführt haben, zeigen, dass eine vollständige GC 10-50 ms dauert und die anderen Threads während dieser Zeit nicht unbedingt stoppt (es sei denn, sie versuchen, verwalteten Speicher zuzuweisen), was für uns in Ordnung ist. Ich bin mir aber nicht sicher, ob diese Zahlen für jede Art von Anwendung verallgemeinert werden können, Sie sollten wahrscheinlich Ihr eigenes Profiling durchführen, um sicher zu sein.

Wenn Sie befürchten, dass Ihre grafische Benutzeroberfläche (GUI) Ihre Echtzeitvorgaben nicht einhält, können Sie die eigentliche Bildverarbeitung in einen separaten Prozess auslagern und mit der GUI über Pipes/Sockets kommunizieren. Oder Sie sollten diese Option zumindest im Hinterkopf behalten, wenn Sie Ihr System entwerfen, damit Sie sie als Worst-Case-Option haben, falls Sie wirklich auf unvorhergesehene Leistungsprobleme stoßen.

Ihre zweite Frage war, ob Sie C++ oder C# für die eigentlichen Algorithmen verwenden sollten. Ich persönlich fühle mich in C++ wohler, wenn ich komplexe Bildverarbeitungsalgorithmen schreibe. Ich denke, die Sprache ist für die Aufgabe besser geeignet, und es gibt weitaus mehr Bibliotheken für Numbercrunching in C/C++ als in C#. Aber das ist vielleicht nur eine Frage der persönlichen Vorlieben. Aus Sicht der Leistung hat C++ den Vorteil, dass der C++-Inliner besser ist als der .NET JIT-Inliner (d. h. er kann mehr kleine Funktionsaufrufe inlinen).

Wenn Sie sich für C++ entscheiden, empfehle ich die Verwendung von C++/CLI: Auf diese Weise können Sie C++-Klassen schreiben, die in verwalteten Code kompiliert werden. Der C++-Optimierer wird sie optimieren, nur der letzte Schritt der Kompilierung in nativen Code wird vom .NET JIT durchgeführt. Der große Vorteil ist, dass Sie von C++/CLI aus direkt auf Ihre .NET-Klassen zugreifen können, und Sie können in C++/CLI problemlos verwaltete Klassen erstellen, auf die von C# aus zugegriffen werden kann. Sie müssen nicht auf beiden Seiten des Zauns Wrapper-Code schreiben. (C++/CLI ist etwas umständlich, weil es Sprachkonstrukte für verwaltete und für nicht verwaltete Programmierung enthält, aber wenn Sie bereits mit nicht verwaltetem C++ und C# vertraut sind, werden Sie wahrscheinlich keine Probleme haben, es zu verstehen).

5voto

Eric Smith Punkte 4982

Das erste, was Sie tun müssen, ist Testen Sie Ihre Vermutung . Welche Leistungseinschränkungen haben Sie? Welche Art von Hardware erwarten Sie für den Betrieb der Anwendung? Schreiben Sie ein kleines Programm in C#, das sich mit dem Kernproblem befasst, und messen Sie, wie schnell es läuft.

Erst wenn Sie die Fakten kennen, können Sie entscheiden, ob Sie C/C++ gegenüber einer verwalteten Lösung bevorzugen oder nicht.

Zusammen mit anderen Kommentatoren vermute ich, dass eine C#/managed Lösung sehr gut funktioniert, insbesondere wenn Sie die .NET Parallele Erweiterungen .

Wenn Sie sich für den C/C++-Weg entscheiden, dann gibt es zwei Optionen für Interop, nämlich pInvoke und COM-Interoperabilität . Ich glaube nicht, dass es einen sauberen Weg gibt, um auf nicht verwaltete C++-Klassen direkt von .NET aus zuzugreifen; zu diesem Zweck müssten Sie Folgendes in Betracht ziehen Implementierung einer verwalteten/unverwalteten C++-Assembly .

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