Probleme mit Serialisierung / speichern



  • Hallo.
    Ich habe mit VS Express 2008 ein Programm zur Erzeugung von Konfigurationsdateien für einen DSP geschrieben.
    Das ganze sieht in etwa so aus, dass es mehrere Reiter gibt (z.B PWM,ADC,Timer...), in welchen sich dann jeweis
    eine vielzahl von Dropboxen / Textboxen zum Einstellen der Werte befinden.
    Diese Werte werden über set Methoden in Klassen (als private variablen) abgespeichert


    für Timer1, Timer 2, Timer 3 usw. gespeichert werden müssen)
    Da das Programm jetzt ganz gut funktioniert, wollte ich noch die möglichkeit hinzufügen, die Einstellungen die man
    gemacht hat nicht nur als Konfigurationsdateien zu exportieren, sondern auch als Programmspezifische Datei,
    die man wieder öffnen kann.

    Alle Objekte zur Speicherung der Eingabewerte werden in Form1 erzeugt (Form1 ist das Hauptfenster welches automatisch
    von VS erstellt wird, wenn man ein neues Windows-Forms Projekt erstellt).

    Jetzt wollte ich (so kannte ich es aus c#) alle Klassen als [Serializable] deklarieren, und dann einem BinaryFormatter übergeben.

    Wenn ich aber eine meiner speicherklassen als [Serializable] deklariere
    bekomme ich folgende Fehlermeldung:

    1>c:\dokumente und einstellungen\llirak2\eigene dateien\visual studio 2008\projects\config-interface\config-interface\adc_element.h(20) : error C3115: 
    "System::SerializableAttribute": Dieses Attribut ist für "adc_element" nicht zulässig.
    
    1>        c:\windows\microsoft.net\framework\v2.0.50727\mscorlib.dll: Siehe Deklaration von 'System::SerializableAttribute'
    1>        Das Attribut kann nur angewendet werden auf: 'ref class', 'delegate', 'enum class', 'value class'
    

    hier mal die kleinste meiner Speicherklassen:

    #pragma once 
    
    #include "string"
    #include "fstream"
    
    #using <system.dll>
    #using <system.messaging.dll>
    
    using namespace System::Runtime::Serialization;
    using namespace System::IO;
    using namespace System;
    using namespace std;
    
    [Serializable] 
    class adc_element
    {
    
    public:
    		adc_element();
    		~adc_element();
    
    		void set_CPUName(string CPUName);
    		void set_Sequence(int sequence);
    		void set_SignalName(string SignalName);
    		void print_tofile(ofstream& save_stream);
    		bool is_Sequence_set();
    
    private:
    	bool used,Sequence_set;
    	string CPUName,SignalName;
    	int sequence;
    };
    

    Hat jemand eine Idee, wie ich das lösen könnte?
    Es muss auch nicht unbedingt mit dem BinaryFormatter gelöst werden, aber ich glaube um das ganze als XML
    zu speichern hätte ich früher mit der Implementierung anfangen sollen....

    Bin für alle Anregungen dankbar !



  • Du musst schon eine C++/CLI Klasse oder Struct machen. Deine ist native.

    Also z.B.

    [Serializable]
    ref class adc_element 
    {
       // ...
    };
    


  • das hatte ich auch schon versucht, aber dann hagelt es Fehler

    http://filebin.ca/kkwqe/BuildLog.htm



  • Ja, logisch, weil Du native typen in einer managed Klasse verwendest (z.B. std::string).

    Du musst schon eine saubere "Bridge" bauen oder noch besser, alles in .NET oder alles in native C++ machen.

    Benutzt Du C++/CLI weil Du native Code in .NET integrieren möchtest?
    Wenn ja: ➡ Bridge
    Wenn nein: ➡ Entweder managed oder native

    Simon



  • ich benutzte C++/CLI, weil ich von c# auf c++ umsteigen musste für dieses Projekt, und alle Bücher die ich zum Thema c++ hatte aus einer Zeit vor c++ .net stammen.

    Ich habe erst im Laufe der Zeit gemerkt, dass sich in c++ .net doch einiges geändert hat, aber leider keine gute Dokumentation gefunden, die die unterschiede erklärt. Deswegen ist da jetzt einiges durcheinander geraten.

    Bedeutet das, um serialisieren zu können, muss ich den Code komplett auf managed c++ umschschreiben ?



  • Bedeutet das, um serialisieren zu können, muss ich den Code komplett auf managed c++ umschschreiben ?

    Nicht komplett. Aber dort wo ein [Serializable] Attribute verlangt ist schon. Es reicht ein dünner Wrapper, der das Mapping vornimmt.

    Es ist ja sowiso unerlässlich, da Du die .NET Serialisierung benutzen möchtest (möchtest Du, oder?). Diese kennt aber Typen wie std::string nicht.

    Simon



  • Oh je,
    da das Programm nicht viel mehr tut, als (sehr) viele Werte entgegenzunehmen, in Klassen zu speichern und formatiert wieder auszugeben, bedeutet das Quasi, das ich alles nochmal überarbeiten muss.

    Hast du vielleicht noch ein paar mehr Info's zu dem Wrapper den du erwähnt hast. Das wäre sehr hilfreich (hoffe ich)...



  • Warum möchtest Du denn überhaupt Serialisieren?



  • nunja, wenn man sich erstmal durch die ganzen Einstellungen gearbeitet, und seine Konfigurationsdateien erzeugt hat , dann aber zwei Wochen später bemerkt, dass der DSP doch nicht genau das tut was er soll, wäre es doch schöner, wenn man einfach nur eine Datei laden könnte und die fehlerhaften Werte ändert, anstatt wieder von 0 anzufangen...

    Es geht mir im Grunde nur darum, die Werte, welche der Benutzer eingestellt hat zu einem späteren Zeitpunkt wieder herstellen zu können. Auf welche Art und Weise das geschieht ist mir eigentlich egal. Mit Serialisierung hatte ich nur in c# schonmal Erfahrungen gemacht



  • Woher kriegst Du denn die Werte?

    Ich würde Dir raten bei einer Sprache zu bleiben (C#, C++/CLI oder native C++).
    Meiner Meinung ist der Vorteil (nämlich dass bestehender, nativer Code in .NET verwendet werden kann) sehr gering im Verhältnis zum Aufwand.

    So wie ich dich verstanden habe, ist dein Programm mehr ein Tool, dass dir die Arbeit erleichtern soll. Das hat, nehme ich an, noch keine riesen Codebasis.

    Wenn Du jetzt schon Code in native C++ hast würde ich dabei bleiben. Ev. reicht ja ein Commandline Tool.

    Simon



  • Also nur damit man sich besser vorstellen kann um was es geht hab ich mal ein paar screenshots von dem Programm gemacht

    http://www.mypicx.com/05282009/configcreator/

    Das ist nur ein kleiner Teil der Werte die man einstellen kann, deswegen fällt ein commandlinetool schonmal flach, würde ich sagen 😉

    Hätte ich vorher über die Unterschiede von native c++ und c++ .Net Bescheid gewusst, wäre ich natürlich auch bei einer Sprache geblieben, und hätte mir dadurch wahrscheinlich auch noch einiges an Arbeit gespart, da ich doch häufiger mit Problemen zu kämpfen hatte Variablen und Objekte zwischen Managed und Unmanaged zu konvertieren (ist mir aber auch erst jetzt klar geworden, woher die Probleme kamen).
    Im Nachhinein war mein herangehen sehr blauäugig, ich wusste aber auch nicht von Beginn an, das es doch so ein relativ (für meine Verältnisse) umfangreiches Programm werden würde.

    Die Funktionalität zum Speichern wäre mir schon sehr wichtig, deswegen denke ich (soweit ich das jetzt verstanden habe), dass mir nichts anderes übrig bleibt, als den Code nochmal umzuschreiben ?

    Ich arbeite mich grade mit Unterstützung der Seite
    http://www.visualcplusdotnet.com
    durch die Unterschiede... auch wenn sie aussieht wie "straight from the 80s" ist sie doch sehr hilfreich



  • Ich glaub ich würds mir in ein File (Text oder XML) speichern und mit einem guten Editor editieren.

    Die nächste Wahl wäre dann, wenns mit GUI sein müsste, alles in C# zu machen.

    Oder kombiniert, mit dem bestehenden Code (C++, so wie ich dich verstanden habe) die Werte in ein File schreiben und mit dem C# Editor das File editieren.

    Simon



  • ich habe mich entschlossen, die bestehenden Klassen so umzuschreiben, dass
    sie Serialisierbar sind.

    Das klappt auch soweit ganz gut, aber an einigen Stellen hakelt es noch:
    Ich erzeuge in Form1 ein Element der Klasse adc.h

    der Code dieser Klasse sieht so aus:

    #pragma once 
    
    #include "fstream"
    #include "adc_element.h"
    #include "adc_setting.h"
    
    #define ARRAY_SIZE 8
    
    #using <system.dll>
    #using <system.messaging.dll>
    
    using namespace System::Runtime::Serialization;
    using namespace System::IO;
    using namespace System;
    using namespace std;
    
    [Serializable] 
    ref class adc
    {
    public:
    	adc()
    	{
    		this->A=gcnew array <adc_element^>(ARRAY_SIZE);
    		this->B=gcnew array <adc_element^>(ARRAY_SIZE);
    		for (int i=0; i < ARRAY_SIZE; i++)
    		{
    			A[i] = gcnew adc_element;
    			B[i] = gcnew adc_element;
    		}
    	}
    	array< adc_element^ >^ A;
    	array< adc_element^ >^ B;
    	static adc_setting^settings =gcnew adc_setting;
    };
    

    Wenn ich dieses Objekt nun Serialisiere, werden die Werte, die in "adc_setting"/ "settings" gespeichert sind korrekt serialisiert, und
    lassen sich auch problemlos wieder deserialisieren.

    Aber die Werte welche in den Arrays für die "adc_element" Objekte gespeichert sind, gehen verloren.

    Gibt es eine möglichkeit auch diese zu serialisieren ?


Anmelden zum Antworten