Hilfe bei Verwendung mehrerer Objekte (Managed/Unmanaged)
-
Hallo Leute!
Ich bin eigentlich eher ein C#-Heini und habe mich jetzt etwas in die C++ Welt verlaufen. Ich werde mal versuchen zu erklären, was ich möchte und wo mein Problem liegt. Achso, ich entwickel mit VS2005.
Ich möchte für eine unmanaged C++ Klasse eine Wrapper-Klasse schreiben um sie in .NET verwenden zu können. Dabei hat sie jetzt leider ein Problemchen ergeben.
Das Erstellen der Wrapper Klasse hat soweit funktioniert, solange ich nur ein Objekt davon erzeuge. jetzt benötige ich aber mehrere Objekte. Ich benötige in jedem manged Objekt ein unmanaged Objekt. und da liegt irgendwie mein Problem.
Meine Wrapper Projekt besteht aus 3 Dateien: unmanaged.cpp managed.cpp und header.h.
die header.h enthält die Deklarationen sowohl der managed, als auch der umanaged Klasse. Die managed Klasse wird von einem Namespace umgeben. in der h-Datei wollte ich nun innerhalb der ref-Klasse eine Instanz der unmanaged Klasse erzeugen.public ref class ManagedClass { UnmangedClass * unmangedObject }
doch dies schlägt leider fehlt. (Error C2143: Syntaxfehler: Es fehlt ein ';' vor '*')
Ich kann dies nur in der managed.cpp vornehmen.namespace Wrapper{ UnmangedClass * unmangedObject }
aber das funktioniert nicht. Ich bekomme dann für alle meine managed Objekte nur ein unmanaged Objekt.
Aber ich brauche halt für jedes managed Objekt ein eigenes unmanaged Objekt. Ich tippe ja momentan auf einen Syntaxfehler...
Kann mir vielleicht jemand helfen? Ein CSharper steht grad bissle aufm Schlauch
-
Suche mal nach gcroot.
Ich denke, das ist das was Du brauchst.
Grüsse Simon
-
Also abgesehen davon, dass hinter unmangedObject ein Semikolon fehlt, findet er UnmangedClass nicht. Muss es Wrapper::UnmangedClass heißen?
-
Also das fehlende Semikolon ist ein Tippfehler von mir hier im Post. im Quelltext steht es drin.
Warum muss es Wrapper::Unmanaged heißen? Muss unmanaged mit in den Namespace? habe da bisher nur die Klasse managed drin...
also gcroot brauche ich ja nur, wenn ich vom unmanaged auf den managed bereich zugreifen will oder nicht? ich will ja aber vom managed in den unmanaged Bereich...
Im Prinzip bin ich der Meinung, dass meine h-Datei in etwa so aussehen müsste:
namespace Wrapper{ public ref class ManagedClass { unmanagedClass * unmangedObject; // weitere Deklarationen } } class unmanagedClass { // Deklarationen }
doch das geht nicht, weil er dann an dem Punkt unmanagedClass * unmanagedObject rummeckert...
Nur wenn ich das direkt in die managed.cpp Datei schreibe, bekomme ich ohne Fehler zum Laufen. dann allerdings nur mit einem gemeinsamen unmanagedObject für alle managed Objekte...Momentan sieht die managed.cpp so aus:
#include ... namespace Wrapper{ unmanagedClass * unmanagedObject; managedClass::managedClass() { } // weitere Methoden }
-
Du musst in C++ Klassen und Structs mit einem Semikolon abschließen, Erbe aus C-Zeiten. Probier# mal sowas:
namespace Wrapper{ public ref class ManagedClass { unmanagedClass * unmangedObject; // weitere Deklarationen }; } class unmanagedClass { // Deklarationen };
-
die managed class sollte ein unmanaged member haben.
jezt ist das unmanaged objekt (besser gesagt der pointer drauf) ein globales (im namespace Wrapper) objekt.Poste doch mal den ganzen (oder durchgängigen) code. Der code den Du uns zeigst läuft hinten und vorne nicht.
-
okay, hier mal der Quelltext. ich hab mal die Methoden der Klassen weg gelassen, da es sonst unübersichtlich wird.
// header.h #pragma once #include "unmanagedClassXYZLib.h" #include "stdafx.h" #include <vcclr.h> using namespace System; namespace Wrapper { public ref class managedClass { // TODO: Die Methoden für diese Klasse hier hinzufügen. public: managedClass(); ~managedClass(); // Methoden internal: private: }; } class unmanagedClass : public unmanagedClassXYZLib { public: unmanagedClass(); ~unmanagedClass(); public: private: }; // managed.cpp #include "stdafx.h" #include "header.h" namespace Wrapper { unmanagedClass * unmanagedObject; managedClass::managedClass() { // TODO: Die Methoden für diese Klasse hier hinzufügen. unmanagedObject = new unmanagedClass(); } managedClass::~managedClass() { delete unmanagedObject; } } // unmanaged.cpp #if _MSC_VER > 1000 #pragma once #include "stdafx.h" #include "header.h" unmanagedClass::unmanagedClass() { } unmanagedClass::~unmanagedClass() { }
PS: die Bezeichen "managed" und "unmanaged" sind hier erfunden, damit es (hoffentlich) übersichtlicher wird
-
Also ich habe es mal nachvollzogen und bei mir scheint es zu laufen:
#pragma once #include "stdafx.h" #include <vcclr.h> using namespace System; class unmanagedClassXYZLib { }; class unmanagedClass : public unmanagedClassXYZLib { public: unmanagedClass() {} ~unmanagedClass() {} }; namespace Wrapper { public ref class managedClass { // TODO: Die Methoden für diese Klasse hier hinzufügen. unmanagedClass * unmanagedObject; public: managedClass::managedClass() { // TODO: Die Methoden für diese Klasse hier hinzufügen. unmanagedObject = new unmanagedClass(); } managedClass::~managedClass() { delete unmanagedObject; } }; }
// CPPConsole.cpp : main project file. #include "stdafx.h" #include "header.h" using namespace System; int main(array<System::String ^> ^args) { Wrapper::managedClass c1; Wrapper::managedClass c2; Wrapper::managedClass c3; Wrapper::managedClass c4; Wrapper::managedClass c5; return 0; }
Die erzeugten Objekte enthalten eigene unmanaged Objekte.
Wolltest Du sowas haben?
-
Danke für den Code!
Habe das ganze eben mal getestet und bei mir läuft es auch.
was du anders machst als ich, ist die Reihenfolge der Klassendeklaration.
Du deklarierst erst die unmanaged und dann die managed Klasse. wenn ich die Reihenfolge ändere, geht es nicht mehr.
wenn ich das bei mir mache, dann geht es aber auch nicht, da ich vom unmanaged auch auf den managed Bereich zugreifen muss (mit gcroot) und dann bekomme ich deswegen Fehlermeldungen...
-
namespace Wrapper { unmanagedClass * unmanagedObject; // das hier ist nicht ok bei dir, denn es ist eine globale variable und ich denke desshalb gehts nicht.
-
Nighthawk167 schrieb:
Du deklarierst erst die unmanaged und dann die managed Klasse. wenn ich die Reihenfolge ändere, geht es nicht mehr.
wenn ich das bei mir mache, dann geht es aber auch nicht, da ich vom unmanaged auch auf den managed Bereich zugreifen muss (mit gcroot) und dann bekomme ich deswegen Fehlermeldungen...
dann mach eine Forwarddeklaration:
namespace Wrapper { ref class managedClass; }
Vor dem Zugriff der unmanaged auf die managed Klasse
-
da stimme ich dir zu, dass das falsch ist. das muss da weg. nur so läuft es wenigstens halbwegs (mit nur einem unmanagedObject)
ich habe mal die h-Datei von witte "verschlimmbessert"
#pragma once #include "stdafx.h" #include <vcclr.h> using namespace System; namespace Wrapper { public ref class managedClass { unmanagedClass * unmanagedObject; public: managedClass::managedClass() { unmanagedObject = new unmanagedClass(); } managedClass::~managedClass() { delete unmanagedObject; } }; } public class unmanagedClassXYZLib { }; public class unmanagedClass : public unmanagedClassXYZLib { public: unmanagedClass() { } ~unmanagedClass() { } };
hab nur die managed Klasse nach oben verschoben und dann geht es leider nicht mehr.
mein Problem ist jetzt, dass ich nicht nur vom managed in den unmanaged Bereich muss, sondern auch vom unmanaged in den managed bereich. wenn ich meine h-Datei so umstrukturiere, dass die unmanaged Klasse oben steht, dann funktioniert der Weg vom unmanaged in den managed Bereich nicht mehr
-
Danke witte!
die Forwarddeklaration hat gefehlt. da wäre ich wahrscheinlich im Leben nicht drauf gekommen.
Also es funktioniert jetzt. ich kann jetzt von meiner managed Klasse mehrere Objekte erzeugen, die jeweils "ihr eigenes" Objekt der unmanaged Klasse erzeugen und von diesem unmanaged Objekt kann ich nun auch zurück auf das aufrufende (!) managed Objekt zugreifen.
Hier noch einmal der endgültige Code:
#pragma once #include "stdafx.h" #include <vcclr.h> using namespace System; namespace Wrapper { ref class managedClass; } public class unmanagedClassXYZLib { }; public class unmanagedClass : public unmanagedClassXYZLib { public: unmanagedClass(Wrapper::managedClass^ _managedObject) { managedObject = _managedObject; } ~unmanagedClass() { } private: gcroot<Wrapper::managedClass^> managedObject; }; namespace Wrapper { public ref class managedClass { unmanagedClass * unmanagedObject; public: managedClass::managedClass() { unmanagedObject = new unmanagedClass(this); } managedClass::~managedClass() { delete unmanagedObject; } }; }
Nochmals Danke für eure Hilfe!