WPF und native C++
-
Morgen,
Ich habe viel nativen C++ Code, und möchte darum nun eine GUI Anwendung basteln. Ich spiele mit dem Gedanken WPF zu benutzen.
Meine Fragen:- WPF ist ja .NET. MUSS ich zur WPF Entwicklung C# benutzen?
- Sagen wir ich benutze C# für WPF. Wie kann ich dann in C# meinen C++ Code benutzen? Im Moment dachte ich daran, eine Art Zwischenschicht mit C++/CLI zu erzeugen. Konkrete würde das vllt so aussehen: Ich habe 3 Projekte in meiner VS Solution:
a) Ein Managed C# WPF Projekt
b) Ein Managed C++/CLI Projekt (kompiliert zu einer Managed .dll), in dem ich um alle nativen C++ Klassen einen C++/CLI Wrapper baue
c) Ein natives C++ Projekt (kompiliert zu einer nativen .lib)
b) benutzt c) und a) benutzt b)
Würde das so gehen? Und wäre es gut?
-
flo_ schrieb:
- WPF ist ja .NET. MUSS ich zur WPF Entwicklung C# benutzen?
Nein. WPF funktioniert grundsätzlich mit jeder .Net Sprache. Allerdings würde ich dir nicht empfehlen, dazu C++/CLI zu nehmen, da C++/CLI in erster Linie als Verbindungssprache gedacht ist.
flo_ schrieb:
- Sagen wir ich benutze C# für WPF. Wie kann ich dann in C# meinen C++ Code benutzen?
Da gibt es mehrere Möglichkeiten. Eine Möglichkeit hast du schon angesprochen, ich werde nachher noch auf diese eingehen und eine zweite Möglichkeit dort aufzeigen.
Zwei weitere Möglichkeiten sind:
1. Du bietes eine C Schnittstelle an und bindest diese Schnittstelle über P/Invoke in das C# Programm ein.
2. Du bietes eine COM Schnittstelle an und bindest diese über COM Interop in dein C# Programm ein.Die erste Möglichkeit ist direkt und meistens unkompliziert. Die Nachteile sind in der etwas aufwendigen Syntax und dem eher langsamen Aufruf zu finden. Wenn du die Schnittstelle also oft benutzt und diese schnell sein muss, dann würde ich nicht unbedingt P/Invoke einsetzen.
Die zweite Möglichkeit würde ich überhaupt nicht einsetzen, weil ich COM nicht mag. Meiner Meinung nach ist COM unübersichtlich und unlogisch. Das muss aber natürlich jeder für sich selbst entscheiden.flo_ schrieb:
Im Moment dachte ich daran, eine Art Zwischenschicht mit C++/CLI zu erzeugen. Konkrete würde das vllt so aussehen: Ich habe 3 Projekte in meiner VS Solution:
a) Ein Managed C# WPF Projekt
b) Ein Managed C++/CLI Projekt (kompiliert zu einer Managed .dll), in dem ich um alle nativen C++ Klassen einen C++/CLI Wrapper baue
c) Ein natives C++ Projekt (kompiliert zu einer nativen .lib)b) benutzt c) und a) benutzt b)
Würde das so gehen? Und wäre es gut?Dies sollte grundsätzlich gehen, ich würde dir allerdings empfehlen, das native C++ Projekt auch als DLL zu erstellen. Du kommst sonst wahrscheinlich in ein paar Linker Probleme.
Eine Alternative wäre übrigens noch, dass du das C++ Projekt direkt auf C++/CLI umstellst. C++/CLI sollte C++ Code ohne Probleme kompilieren können. So sparst du dir eine DLL ein. Ich würde einfach empfehlen, dass du im Code eine gute Trennung machst, so dass man den C++ Code ohne Probleme heraustrennen könnte, falls man dies einmal möchte.Noch einen Tipp zur ganzen Interop Geschichte:
Im WPF Projekt unbedingt die Einstellung "Target CPU" von "Any CPU" auf "x86" oder "x64" umstellen, je nach dem in welchem Format deine native und/oder C++/CLI DLL vorliegt. Sonst wirst du ein paarBadImageFormatException
bekommenGrüssli
-
WPF funktioniert grundsätzlich mit jeder .Net Sprache.
Die WPF- spezifischen Tools sind aber nicht für jede .NET Sprache ausgelegt.
-
theta schrieb:
WPF funktioniert grundsätzlich mit jeder .Net Sprache.
Die WPF- spezifischen Tools sind aber nicht für jede .NET Sprache ausgelegt.
Deshalb schrieb ich grundsätzlich
Ich weiss, dass es schlecht mit C++/CLI funktioniert. Mit Visual Basic .Net soll es aber ganz gut gehen. Mit C# geht es gut. Weiss einer wie es mit F# aussieht? Und was ist mit den restlichen X Sprachen?Grüssli
-
Hallo!
Ich bins nochmal. Leider ist das bei mir nun doch problematischer als angenommen.
Folgende Situation: Ich habe im Moment meine 3D-Engine (geschrieben in DX10 und nativem C++) und einen Editor, geschrieben in C++/CLI und Winforms. Ich habe mich für C++/CLI entschieden, weil ich dann meinen nativen Code einfach so benutzen kann, ohne Wrapper oder so (hätte auch lieber C# genommen, weil ich das schöner finde).Jetzt habe ich mit dem Gedanken gespielt von WinForms zu WPF und C# zu wechseln (WPF und C++/CLI macht mMn keinen Sinn). Das große Problem: Ich habe eine sehr, sehr rege Interaktion zwischen Editor (Managed C++/CLI Code) und meinem nativen C++ Code.
Sowas ist z.B. bei mir normaler C++/CLI Code meines Editors:void EditorForm::OnResize(Panel^ panel) { mDefCamera = mSceneManager->createCamera("default"); float aspectRatio = static_cast<float>(pnlVP0->Size.Width) / pnlVP0->Size.Height; mDefCamera->setProjectionPerspective(aspectRatio, math::PI_QUARTER, 1, 10000); // 60000000 DefCamera->setViewFrame(math::Vec3(400, 400, 400)); cullLODDesc = new TerrainCLDesc; cullLODDesc->technique = TCL_VIEWFRUSTUM_GEOMIPMAPPING; mTerrain = mSceneManager->getDefaultTerrain(); mTerrain->createVertexPlane(1025, *cullLODDesc, 10, 1);
Die ganzen Klassen, Methoden etc. in dieser C++/CLI Methode kommen alle aus meiner nativen C++ Lib. Ich kann die Interaktion auch nicht einfach streichen: Ich benutze im Editor nun mal massiv meine Engine.
Wenn ich jetzt auf WPF/C# umsteigen, dann muss ich doch um all die Klassen, die ich im Editor benutze (und das sind VIELE!) einen C++/CLI Wrapper schreiben, oder? Das wäre für mich der absolute Alptraum!
Wie könnte ich das lösen?
Es wurde auch schon vorgeschlagen, meine ganze native C++ Lib einfach mit /clr zu kompilieren. Aber das will ich eigentlich nicht. Ich hab die ja nur in C++ geschrieben wegen Performance und wenn ich meine native C++ Lib mit /clr kompiliere, dann wird das doch MSIL und bei der Ausführung JIT Compiled, oder? (sprich bestimt 2-5% langsamer?) Außerdem versteh ich nicht ganz, wie ich das dann aus C# benutzen soll.
Sagen wir ich habe in meinem nativen C++ diese Methode: Foo::bar(std::vector<Decal>& s); Das kompiliere ich jetzt mit /clr. Wie rufe ich diese Methode dann aus C# auf? Raff ich nicht, wie das gehen soll.Danke für jede Hilfe!
-
flo_ schrieb:
Folgende Situation: Ich habe im Moment meine 3D-Engine (geschrieben in DX10 und nativem C++) und einen Editor, geschrieben in C++/CLI und Winforms. Ich habe mich für C++/CLI entschieden, weil ich dann meinen nativen Code einfach so benutzen kann, ohne Wrapper oder so (hätte auch lieber C# genommen, weil ich das schöner finde).
Das macht bereits keinen Sinn.
flo_ schrieb:
Wenn ich jetzt auf WPF/C# umsteigen, dann muss ich doch um all die Klassen, die ich im Editor benutze (und das sind VIELE!) einen C++/CLI Wrapper schreiben, oder? Das wäre für mich der absolute Alptraum!
Es hat niemand behauptet, dass dies einfach sei oder wenig Arbeit gibt. Solche Interop Dinge fordern meistens eine rechte Menge an zusätzlicher Arbeit.
flo_ schrieb:
Es wurde auch schon vorgeschlagen, meine ganze native C++ Lib einfach mit /clr zu kompilieren. Aber das will ich eigentlich nicht. Ich hab die ja nur in C++ geschrieben wegen Performance und wenn ich meine native C++ Lib mit /clr kompiliere, dann wird das doch MSIL und bei der Ausführung JIT Compiled, oder? (sprich bestimt 2-5% langsamer?)
C++/CLI wird in Maschinensprache und CIL übersetzt. C++/CLI ist deshalb meistens ein paar Prozentpunkte schneller als ein normales .Net Programm. Nur was wirklich als .Net benötigt wird, wird auch in CIL übersetzt.
flo_ schrieb:
Außerdem versteh ich nicht ganz, wie ich das dann aus C# benutzen soll.
Indem du in C++/CLI .Net Wrapper schreibst
flo_ schrieb:
Sagen wir ich habe in meinem nativen C++ diese Methode: Foo::bar(std::vector<Decal>& s); Das kompiliere ich jetzt mit /clr. Wie rufe ich diese Methode dann aus C# auf? Raff ich nicht, wie das gehen soll.
Kannst du nicht. Wie gesagt, du musst dazu trotzdem einen Wrapper schreiben. Mir ging es nur darum, dass du nicht noch eine zusätzliche DLL hast. Auch kann der Kompiler unter Umständen ein bisschen besser optimieren, da es nicht nochmals über eine DLL Grenze geht.
Grüssli
-
Dravere schrieb:
C++/CLI wird in Maschinensprache und CIL übersetzt. C++/CLI ist deshalb meistens ein paar Prozentpunkte schneller als ein normales .Net Programm. Nur was wirklich als .Net benötigt wird, wird auch in CIL übersetzt.
Soweit ich weiss eigentlich genau umgekehrt: alles IL ausser da wo nicht geht (printf und so Scheiss).
Ich glaube mich auch zu erinnern gelesen zu haben, dass der leichte Geschwindigkeits-Vorteil von C++/CLI einfach vom besseren Optimizer kommt.
-
hustbaer schrieb:
Dravere schrieb:
C++/CLI wird in Maschinensprache und CIL übersetzt. C++/CLI ist deshalb meistens ein paar Prozentpunkte schneller als ein normales .Net Programm. Nur was wirklich als .Net benötigt wird, wird auch in CIL übersetzt.
Soweit ich weiss eigentlich genau umgekehrt: alles IL ausser da wo nicht geht (printf und so Scheiss).
Ich glaube mich auch zu erinnern gelesen zu haben, dass der leichte Geschwindigkeits-Vorteil von C++/CLI einfach vom besseren Optimizer kommt.Ich würde jetzt nicht meine Hand ins Feuer legen. So wie ich es bisher verstanden habe, kommt dies ein wenig auf die Kompileroption an. Wenn man das ganze Projekt mit /clr kompiliert, wird glaub ich, so viel wie möglich in CIL übersetzt. Man kann aber auch nur einzelne Files mit /clr übersetzen, dann werden nur diese Module in CIL übersetzt und der Rest bleibt als Maschinencode erhalten.
Hier sollte man wohl weitere Informationen finden, hab die Dokumente aber noch nicht genauer angeschaut:
http://msdn.microsoft.com/en-us/library/k8d11d4s.aspx
http://msdn.microsoft.com/en-us/library/x0w2664k.aspxGrüssli