C++ Framework mit C# GUI-Code verbinden


  • Administrator

    Jochen Kalmbach schrieb:

    Warum soll man in C++/CLI nochmals was wrappen? Man kan hier native C/C++ direkt verwenden.

    Du kannst die C++ Klassen zwar in C++/CLI verwenden aber dann nicht in C#. Um sie in C# verwenden zu können, musst du einen Wrapper bauen.

    Grüssli



  • Dravere schrieb:

    Jochen Kalmbach schrieb:

    Warum soll man in C++/CLI nochmals was wrappen? Man kan hier native C/C++ direkt verwenden.

    Du kannst die C++ Klassen zwar in C++/CLI verwenden aber dann nicht in C#. Um sie in C# verwenden zu können, musst du einen Wrapper bauen.

    Und genau davon würde ich abraten. Denn Effektiv verbringst du dann viel Zeit (und vor allem Nerven, das würd ich bei C++/CLI nicht unterschätzen) damit, deinen Wrapper zu bauen, nur damit du dann in C# irgendwelche Logik damit implementierst, die du genausogut gleich in C++/CLI bauen und einfach von C# aus verwenden hättest können. Vor allem: Wenn sich was an dem Code um den der Wrapper gewrapped ist ändert, musst du nicht nur den Wrapper anpassen, sondern auch den C# Code der ihn verwendet. Wenn du einfach die unterste Schicht deiner Logik direkt in C++/CLI implementierst, musst du nur die anpassen/erweitern...

    Wrapper sind meiner Erfahrung nach selten (nie?) eine gute Idee. Bau dir lieber eine Bibkiothek, die genau die Funktionalität implementiert, die du in deiner Anwendung benötigst und nicht nur einfach ein Spiegelbild irgendeiner Library.



  • dot schrieb:

    Wenn du einfach die unterste Schicht deiner Logik direkt in C++/CLI implementierst, musst du nur die anpassen/erweitern...

    Vielleich thast Du ja die Frage nicht ganz verstanden, aber die C++ Klassen sind schon vorhanden... da ist nichts, was man neu machen müsste oder wollte...



  • Dravere schrieb:

    Jochen Kalmbach schrieb:

    Warum soll man in C++/CLI nochmals was wrappen? Man kan hier native C/C++ direkt verwenden.

    Du kannst die C++ Klassen zwar in C++/CLI verwenden aber dann nicht in C#. Um sie in C# verwenden zu können, musst du einen Wrapper bauen.

    Aber du musst mit C++/CLI nur einen Wrapper schreiben.

    A: ein C++/CLI Wrapper um native C++ Klassen

    B: ein C Wrapper um native C++ Klassen + noch ein C# Wrapper um die so entstandene C API

    Was wird wohl im Normalfall weniger Aufwand sein?

    Dravere schrieb:

    Und in C++/CLI musst vieles vom Marshaling selber machen, was vielfach in ein kleines Gefrickel endet. Zumindest ist das meine bisherige Erfahrung 🙂

    In C++ musst du gar kein Marshaling machen. Du schreibst einfach einen managed Wrapper um die native C++ Klassen, und fertig.
    Oder meinst du jetzt so Sachen wie System.String <-> C-String? Das muss man machen, ja. Dafür kann man sich auch aussuchen wie es gemacht wird. Und es gibt ja Haufenweise Helper-Klassen die einem den Grossteil der Arbeit abnehmen.



  • Jochen Kalmbach schrieb:

    dot schrieb:

    Wenn du einfach die unterste Schicht deiner Logik direkt in C++/CLI implementierst, musst du nur die anpassen/erweitern...

    Vielleich thast Du ja die Frage nicht ganz verstanden, aber die C++ Klassen sind schon vorhanden... da ist nichts, was man neu machen müsste oder wollte...

    Wieso, wenn es C++ Klassen sind kann ich sie doch nicht einfach so in .NET verwenden!?



  • Im GOF wird der Adapter auch Wrapper genannt.
    sind also die Patterns aus dem GOF Buch keine gute Idee? 😃



  • David W schrieb:

    sind also die Patterns aus dem GOF Buch keine gute Idee? 😃

    Hältst du Singleton für eine gute Idee? Das steht auch im GoF Buch...

    Das GoF Buch ist trotzdem gut. Das Problem sind nicht die dort beschriebenen Pattern, sondern wie sie verwendet werden.



  • dot schrieb:

    Wieso, wenn es C++ Klassen sind kann ich sie doch nicht einfach so in .NET verwenden!?

    Dann hast Du noch nie C++/CLI gemacht... genau dafür ist die Sprache entworfen worden 🤡



  • dot schrieb:

    David W schrieb:

    sind also die Patterns aus dem GOF Buch keine gute Idee? 😃

    Hältst du Singleton für eine gute Idee?

    Jup.



  • Jochen Kalmbach schrieb:

    dot schrieb:

    Wieso, wenn es C++ Klassen sind kann ich sie doch nicht einfach so in .NET verwenden!?

    Dann hast Du noch nie C++/CLI gemacht... genau dafür ist die Sprache entworfen worden 🤡

    Das hab ich natürlich schon, sonst würd ich hier doch nicht mitdiskutieren. Aber vielleicht gibts ja irgendwas ganz grundlegendes was ich nicht weiß. Könnte es tatsächlich einen Weg geben, wie ich eine native C++ Klasse nehmen kann und diese, ohne auch nur irgendwas an Code zu ändern/hinzuzufügen, direkt in .NET verwenden kann? I don't think so. Zumindest müsste ich eine ref class draus machen. Dann ist es aber keine C++ Klasse mehr...



  • David W schrieb:

    dot schrieb:

    David W schrieb:

    sind also die Patterns aus dem GOF Buch keine gute Idee? 😃

    Hältst du Singleton für eine gute Idee?

    Jup.

    Singleton ist natürlich an sich weder gut noch schlecht. Das Problem ist wieder wie es verwendet wird. Und das wird es leider in 100% (nein, nicht 99.9999%) aller Fälle, die ich bisher je gesehen hab, falsch, obwohl es im GoF Buch richtig steht.

    Aber die Diskussion hatten wir hier schon oft genug 😉


  • Administrator

    @dot,
    Das halte ich für keine gute Idee. Man verwendet die Bibliothek dann meistens nicht nur in diesem Programm. Willst du jedesmal nach C++/CLI greifen und die Logik dort implementieren? Dann musst du auch die anderen Bibliotheken, welche mit dieser interagieren, in C++/CLI verwenden. Am Ende machst du immer alles in C++/CLI und nur gerade das GUI in C#. Ich würde sagen, dass wird recht wartungsunfreundlich.

    Die darunterliegende Bibliothek sollte sich zudem nicht all zu stark verändern. Man wrappt ja normalerweise stabile Versionen. Dadurch verändert sich über die Zeit nicht all zu viel.

    @hustbaer,
    Ich bin davon ausgegangen, dass er eine C Schnittstelle schon anbietet, da er diese ja bereits implementieren wollte. Von daher wird er diese sowieso machen und der Aufwand ist dann gleich.

    In anderen Fällen hast du natürlich recht, dass man noch eine C Schnittstelle entwerfen muss.

    Zum Marshaling:
    Strings und Arrays ja. Ich empfand das als recht mühsam in C++/CLI. Ich hatte aber auch viele Strings zu verarbeiten bei meiner letzten Begegnung mit C++/CLI und dann auch noch zum Teil über unterschiedliche Encodings. Über P/Invoke empfand ich dies als wesentlich angenehmer.

    @David W,
    Die GOF Leute würden das Singleton Pattern heutzutage rausnehmen, wenn sie das Buch nochmals schreiben würden. 😉
    (Finde gerade die Quelle nicht mehr, aber war eine Aussage von einem der vier und wenn ich mich recht erinnere, hatte er mit 2 der anderen darüber gesprochen)

    Grüssli



  • Dravere schrieb:

    @dot,
    Das halte ich für keine gute Idee. Man verwendet die Bibliothek dann meistens nicht nur in diesem Programm. Willst du jedesmal nach C++/CLI greifen und die Logik dort implementieren? Dann musst du auch die anderen Bibliotheken, welche mit dieser interagieren, in C++/CLI verwenden. Am Ende machst du immer alles in C++/CLI und nur gerade das GUI in C#. Ich würde sagen, dass wird recht wartungsunfreundlich.

    Ich weiß nur, dass ich mir bisher jedes Mal, wenn ich was gewrapped hab, früher oder später gewünscht hab, dass ich es nicht gewrapped sondern abstrahiert hätte. Und zwar eigentlich sogar ganz unabhängig davon, in welcher Sprache ich grad unterwegs war. Darum meine Empfehlung nicht zu wrappen sondern zu abstrahieren 😉
    Mag natürlich sein, dass das daran liegt, dass es sich dabei praktisch immer um irgendwelche low-level APIs gehandelt hat...



  • Also, der Klarheit halber:

    1. Das C++-Framework ist in native C++ geschrieben, ist aber noch in der Entwicklung. Das heißt, es ändert sich noch, wobei die Schnittstellenklassen erstmal größtenteils fertig sind, nur die Zahl der möglichen Events wird noch deutlich wachsen.
    2. Die Logik-schicht im Framework wird nicht in C++/CLI geschrieben. Heißt, wie hustbaer sagt, dass eine C++/CLI-Schicht ein reiner Adapter wäre, um auf die native Schnittstelle aus .NET zugreifen zu können.
    3. Wenn ich aber irgendwann™ die C-API sowieso zur Verfügung stellen möchte, ist es doch relativ wurscht, ob ich den .NET-Adapter auf der C-API (in C#) oder auf dem Framework selber (in C++/CLI) aufsetze oder?

    Die Schnittstellen des Frameworks sind relativ simpel gehalten. Ich könnte mir vorstellen, die C-API und evtl. auch den .NET-Adapter zu ~90% generieren zu lassen.



  • Was fehlt ist die Performance-Betrachtung. Zu dem Thema sagt die MSDN:

    http://msdn.microsoft.com/en-us/library/ky8kkddw.aspx

    http://msdn.microsoft.com/en-us/library/aa712982.aspx

    PInvoke has an overhead of between 10 and 30 x86 instructions per call. In addition to this fixed cost, marshaling creates additional overhead. There is no marshaling cost between blittable types that have the same representation in managed and unmanaged code. For example, there is no cost to translate between int and Int32.

    For higher performance, it may be necessary to have fewer PInvoke calls that marshal as much data as possible, rather than have more calls that marshal less data per call. Or somewhat more memorably: prefer a chunky over a chatty API.



  • loks schrieb:

    Was fehlt ist die Performance-Betrachtung.

    Ist in meinem Fall weitgehend irrelevant, da ich

    1. Nur eine GUI an meine Client-Schnittstelle flanschen will (oder nenn es den View im MVC Pattern). Das heißt, durch die Schnittstelle zwischen C# und C++ gehen nur die User-Interaktionen und die Events, die als Reaktion auf diese Interaktionen zurückkommen
    2. Das Ganze nur als Testsystem zum rumspielen haben will, d.h. es wird keine Produktiv-Anwendung sein, die unter Schwerlast läuft oder extrem skalieren muss.

Anmelden zum Antworten