Problem bei der Verwendung von C++ Klassen in C#
-
Hallo,
seit einigen Stunden nun versuche ich schon vergeblich meine in C++ geschriebenen Klassen in C# zu nutzen. Ich habe mir einige Tutorials durchgelesen bzw. angesehen, und habe auch Teilerfoge einfahren können. Allerdings funktioniert das Ganze nicht so wie ich es möchte.
Mein Ziel ist es, die in C++ geschriebenen Klassen in C# zu nutzen, um dort eine graphische Oberfläche für das Programm erstellen zu können. Nun ist das Problem, das ich es nicht schaffe, alle Methoden der Klassen in C# nutzen zu können.
Mittlerweile habe ich die Klassen mittels Wrappern in C# eingebunden, die Methoden, die eine andere Klasse (also nicht z.B. int) als Rückgabewert haben, kann ich aber nicht verwenden.
Ein Beispiel:
Ich möchte mittels der Methode "getField(int index)" das Feld bekommen, welches den angegebenen Index besitzt. Die Methode gehört zur Wrapperklasse "ChessBoard" und soll ein "ChessField" zurückliefern.ChessLibary::ChessField ChessLibary::ChessBoard::getField(int index) { return ChessLibary::ChessField(pBoard->fields[index].getType(), pBoard->fields[index].getIndex(), pBoard->fields[index].isWhite()); }
Kann mir irgendjemand helfen, ist zum verzweifeln...
Gruß Alex
-
C# (sowie das .NET-Framework) können nur mit "managed code" direkt kommunizieren (Alternative: P/Invoke), d.h. die Klassen müssen mittels "ref" deklariert sein: Ref classes and structs (C++/CX)
Dann hast du aber keine nativen C++-Klassen mehr (sondern eben sog. "managed code").Die Alternative besteht darin, entweder oben genanntes P/Invoke mittels nativer C-Schnittstelle zu benutzen (d.h. keine Klassen) oder aber eben eigene Wrapper-Klassen in C++/CLI zu erstellen, welche die Datentransformation zwischen C++ und C# durchführen.
-
Hallo Th69,
danke erstmal für die Antwort.
Die Wrapperklassen sind ref-Klassen, und somit "managed code".
public ref class ChessBoard { public: ChessBoard(); int doMove(Move m); ChessLibary::ChessField getField(int index);
Die unterste Methode funktioniert allerdings nicht, die Fehlermeldung:
Error: class "ChessLibary::ChessField" has no suitable copy constructor
Dabei ist es gar nicht meine Absicht den Copy Konstruktor aufzurufen, ich möchte einfach eine neue Instanz von ChessField erstellen.
-
Kennst sonst jemand von euch eine Schritt für Schritt Erklärung, wie man C++ Code in C# verwenden kann?
Oder würdet ihr einen anderen Weg für eine GUI für C++ Code empfehlen?
Freue mich auf Antworten
-
Hallo Alex,
wieso möchtest du keinen (Default-)Copy-Konstruktor für ChessField anbieten?
Sobald du einen Wert über die Funktion zurückgibst wird der Copy-Konstruktor benötigt (mittels copy elision aber evtl. gar nicht effektiv so aufgerufen).Wenn du natives C++ verwendest, könntest du als GUI auch Qt o.ä. verwenden, s.a. [HOWTO] Welches Toolkit für GUIS?
-
Hallo,
ehrlich gesagt ist es mir egal, ob ich einen Copy-Konstruktor anbiete oder nicht, wenn der Code funktioniert.
Auch nach sehr vielen Versuchen mit einigen Internetsuchen habe ich es nicht geschafft, einen Copy-Konstruktor in C++/CLI zu erstellen.Versuche wie
ChessField(ChessField &cf);
scheiterten, da es mir nicht erlaubt war, eine Referenz auf eine "C++/CLI ref class" zu erstellen.
Das hierChessField(ChessField% cf);
gibt zwar keinen Fehler, macht aber glaube ich auch nicht das was ich will (kenn mich mit C++/CLI so gut wwie gar nicht aus ).
Auch interessant:
namespace ChessLibary { public ref class ChessBoard { public: ChessBoard(); ChessField getField(int index);
soweit alles in Ordnung...
ChessLibary::ChessField ChessLibary::ChessBoard::getField(int index) { return ChessField(); }
... hier dann wieder die Fehlermeldung, dass ein "suitable copy constructor" nicht vorhanden ist.
Wie kann ich das Problem lösen?
Gruß Alex
-
Wenn du willst dass
ChessField
in der CLI Welt ein Reference-Type ist, dann lass die Methode eine Referenz zurückgeben, alsoChessField^
.Wenn du willst dass
ChessField
in der CLI Welt ein Value-Type ist, dann definiereChessField
mit demvalue
Keyword stattref
(value class
oder besser gleichvalue struct
).=> C++/CLI Grundlagen lernen, lernen, popernen
-
Hallo,
danke hustbaer, danke Th69!
Irgendwie habe ich es jetzt hinbekommen (geht bestimmt einfacher, schneller etc.)!Hat man gerade ein Problem (mit eurer Hilfe) gelöst, taucht das nächste auf...
Ich habe mich heute etwas intensiver mit C++/CLI beschäftigt, bin aber ratlos:
Diese (eigentlich recht simple) Methode
int ChessKI::generateMoves(ChessBoard %board, ChessField field) { return pKI->generateMoves(*board.pBoard, (*board.pBoard).fields[field.getIndex()]); }
macht Probleme. Denn zwar klappt das Compilieren ohne Probleme, doch bei der Einbindung in das C#-Projekt hakt es...
Dort zeigt Visual Studio mir dann an, die Methode istnot supported by the language
Wieso taucht dieser Fehler auf???
An dem % kann es nicht liegen, hatte ich auch ohne probiert, selber Fehler...
-
Sorry Leute, aber ich versteh C++/CLI einfach nicht...
ChessMove ^ getLegalMove(int index) { return gcnew ChessMove(pBoard->getLegalMove(index)); }
Warum tauchen hier Fehler wie
Error C2143 syntax error: missing ';' before '^'
oder
Error C2334 unexpected token(s) preceding '{'; skipping apparent function body
auf??
Bislang habe ich es noch nicht geschafft, eine in C++/CLI deklarierte Klasse (z.B. ChessBoard, ChessMove) als Rückgabewert nutzen zu können. Ist das überhaupt möglich?
Vielen Dank schon mal im Voraus!!