Boost::Serialization Problem
-
Hallo,
ich muss für ein Projekt etwas auf Basis der Boost::Serialization-Bibliothek erstellen.
Und zwar muss ich aus einer XML-Datei einen Binärstream erstellen.
Dazu habe ich eine vorgegebene C++-Struktur, die ich dabei benutzen muss
Ich habe dazu schon eine Klasse, Funktionen, Testdateien, ... geschrieben, kriege das alles aber nicht zum laufen.Ich hoffe ihr könnt mir hier helfen.
Ob ich überhaupt richtig vorgegangen bin weiss ich nicht, von daher wäre es hilfreich wenn mir jemand sagen könnte, wie das grundsätzliche Vorgehen dabei wäre.
Wenn das nichts hilft, kann ich hier auch Problemlos meine Sourcen reinschreiben.Ich bin leider nicht wirklich erfahren in der C++-Programmierung, von daher bitte ich euch, meine machmal etwas mühsamen Beschreibungen zu tolerienen.
-
also erstes solltest du dich mal hiermit auseinanderetzen:
http://www.boost.org/doc/libs/1_35_0/libs/serialization/doc/index.htmlman muss so einiges beachten. ich selbst bin aufgrund ihrer export strategie etwas davon abegkommen, denn wenn man 100 serialisierbare klassen hat und viele template klassen, dann sitzt man ne weile beim kompilieren, weil man die export macros nur direktin der main aufrufen darf
aber an sich sollte es funktionieren. eine detailierte problembeschreibun wäre zudem hilfreich!
-
Hi,
Danke für den Link
die Doku hatte ich schon durch. Daraufhin hab ich dann auch erst angefangen mein Prog zu schreiben.Eine genaue Aufgabenbeschreibung ist:
Ich soll aus einer gegebenen XML-Datei(Struktur vorgegeben) einen Binärstream erstellen.
Dazu habe ich eine grobe Stuktur einer C++-Klasse, die ich serialisierbar gestalten soll, dann soll die XML-Datei in die Klasse gelesen werden, und aus der Klasse heraus ein Binärstream erstellt werden.
Das ganze soll mittels dem Boost::Serialization-Paket umgesetzt werden.Hier zum Verdeutlichen noch meine Sourcen:
------------------------------------------------------
Ich habe 3 Klassen:
Klasse Goal[cpp] //goal.cpp #include "goal.h" #include <stdlib.h> #include <stdio.h> #include <string.h> //boost includes #include <boost/serialization/base_object.hpp> //#include <boost/serialization/utility.hpp> #include <boost/serialization/list.hpp> #include <boost/serialization/is_abstract.hpp> #include <boost/archive/xml_iarchive> #include <boost/archive/xml_oarchive> #include <boost/archive/binary_iarchive> #include <boost/archive/binary_oarchive> //Tracing and Logging module //#include "../include/Logger.h" //#include "../include/Tracer.h" TODO: add Logging/Tracing files for testing using namespace std; /** * \brief Constructor of class Goal * \param const string _name, const int _minute, const bool _shootout, const Scored _scored, const bool _penality * \return */ Goal::Goal(const string _name, int &_minute, bool &_shootout, Scored &_scored, bool &_penality) { name = _name; minute = _minute; shootout = _shootout; scored = _scored; penality = _penality; } /** * \brief Output-Operator of class Goal * \param const Goal _goal * \return ostream& */ ostream & operator<<(Goal &_goal) { cout << "Name: " << name <<endl << "Minute: " << minute << endl << "Shootout: " << shootout << endl << "Scored: " << scored << endl << "Penality: " << penality << endl; } [/cpp][cpp] //Goal.h #ifndef _GOAL_H_INCLUDED_ #define _GOAL_H_INCLUDED_ #include <stdlib.h> #include <string.h> //boost includes #include <boost/serialization/base_object.hpp> //#include <boost/serialization/utility.hpp> #include <boost/serialization/list.hpp> #include <boost/serialization/is_abstract.hpp> #include <boost/archive/xml_iarchive> #include <boost/archive/xml_oarchive> #include <boost/archive/binary_iarchive> #include <boost/archive/binary_oarchive> //Tracing and Logging module //#include "../include/Logger.h" //#include "../include/Tracer.h" TODO: add Logging/Tracing files for testing using namespace std; /** * \brief class Goal */ class Goal { private: enum Scored{home=0, visitors=1}; friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned int version) { ar & name; ar & minute; ar & shootout; ar & scored; ar & penality; } string name; int minute; bool shootout; Scored scored; bool penality; public: Goal(){}; Goal(const string _name, int &_minute, bool &_shootout, Scored &_scored, bool &_penality); ~Goal(){}; ostream & operator<<(Goal &_goal); } #endif [/cpp]Klasse Stadium
[cpp] //Stadium.cpp #include "stadium.h" #include <stdlib.h> #include <stdio.h> #include <string.h> //boost includes #include <boost/serialization/base_object.hpp> //#include <boost/serialization/utility.hpp> #include <boost/serialization/list.hpp> #include <boost/serialization/is_abstract.hpp> #include <boost/archive/xml_iarchive> #include <boost/archive/xml_oarchive> #include <boost/archive/binary_iarchive> #include <boost/archive/binary_oarchive> //Tracing and Logging module //#include "../include/Logger.h" //#include "../include/Tracer.h" TODO: add Logging/Tracing files for testing //using namespace std; /** * \brief Constructor of class Stadium * \param const string _name, const string _city, const int _spectators * \return */ Stadium::Stadium(const string _name, const string _city, int &_spectators) { name = _name; city = _city; spectators = _spectators; } /** * \brief Output-Operator of class Stadium * \param const Stadium _stadium * \return ostream& */ ostream & operator<<(Stadium &_stadium) { cout << "Name: " << goal.name <<endl << "City: " << goal.city << endl << "Spectators: " << this->spectators << endl; } [/cpp][cpp] //Stadium.h #ifndef _STADIUM_H_INCLUDED_ #define _STADIUM_H_INCLUDED_ #include <stdlib.h> #include <string.h> //boost includes #include <boost/serialization/base_object.hpp> //#include <boost/serialization/utility.hpp> #include <boost/serialization/list.hpp> #include <boost/serialization/is_abstract.hpp> #include <boost/archive/xml_iarchive> #include <boost/archive/xml_oarchive> #include <boost/archive/binary_iarchive> #include <boost/archive/binary_oarchive> //Tracing and Logging module //#include "../include/Logger.h" //#include "../include/Tracer.h" TODO: add Logging/Tracing files for testing using namespace std; /** * \brief class Stadium */ class Stadium { private: friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned int version) { ar & name; ar & city; ar & spectators; } string name; string city; int spectators; public: Stadium(){}; Stadium(const string _name, const string _city, int &_spectators); } #endif _STADIUM_H_INCLUDED_ [/cpp]Klasse Match:
[cpp] //Match.cpp #include "match.h" #include <time.h> #include <stdlib.h> #include <stdio.h> #include <string.h> //boost includes #include <boost/serialization/base_object.hpp> //#include <boost/serialization/utility.hpp> #include <boost/serialization/list.hpp> #include <boost/serialization/is_abstract.hpp> #include <boost/archive/xml_iarchive.hpp> #include <boost/archive/xml_oarchive.hpp> #include <boost/archive/binary_iarchive.hpp> #include <boost/archive/binary_oarchive.hpp> //Tracing and Logging module //#include "../include/Logger.h" //#include "../include/Tracer.h" TODO: add Logging/Tracing files for testing using namespace std; /** * \brief Constructor of class Match * \param const string _home, const string _visitors, const time_t _kickoff, const Goal _goals[100], const Stadium _stadium * \return */ Match::Match(const string _home, const string _visitors, time_t &_kickoff, Goal &_goals[100], Stadium &_stadium) { home = _home; visitors = _visitors; kickoff = _kickoff; for(unsigned int i = 0; i < sizeof(goals); i++) { goals[i] = _goals[i]; } stadium = _stadium; } /** * \brief Copy-Constructor of class Match * \param const Match _match * \return Match& */ Match& Match::operator = (Match &_match) { home = _match.home; visitors = _match.visitors; kickoff = _match.kickoff; for(unsigned int i = 0; i < sizeof(goals); i++) { goals[i] = _match.goals[i]; } stadium = _match.stadium; } /** * \brief Output-Operator of class Match * \param const Match _match * \return ostream& */ ostream & operator<<(Match &_match) { //TODO: Output-Operator } [/cpp][cpp] //Match.h #ifndef _MATCH_H_INCLUDED_ #def _MATCH_H_INCLUDED_ #include <time.h> #include <stdlib.h> #include <string.h> //boost includes #include <boost/serialization/base_object.hpp> //#include <boost/serialization/utility.hpp> #include <boost/serialization/list.hpp> #include <boost/serialization/is_abstract.hpp> #include <boost/archive/xml_iarchive> #include <boost/archive/xml_oarchive> #include <boost/archive/binary_iarchive> #include <boost/archive/binary_oarchive> //Tracing and Logging module //#include "../include/Logger.h" //#include "../include/Tracer.h" TODO: add Logging/Tracing files for testing using namespace std; /** * \brief class Match */ class Match { private: friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned int version) { ar & home; ar & visitors; ar & kickoff; for (int i=0; i<sizeof(goals); i++) { ar & goals[i]; } ar & stadium; } string home; string visitors; time_t kickoff; Goal goals[100]; Stadium stadium; public: Match(){}; Match(const string _home, const string _visitors, time_t &_kickoff, Goal &_goals[100], Stadium &_stadium); } #endif _MATCH_H_INCLUDED_ [/cpp]Darauf bauen dann meine Funktionen auf (Bausteine für XML und binär):
xml:[cpp] //xml.cpp include <iomanip> #include <iostream> #include <fstream> #include <string> //Tracing and Logging module //#include "../include/Logger.h" //#include "../include/Tracer.h" TODO: add Logging/Tracing files for testing #include <cstdio> #include <boost/config.hpp> #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ using ::remove; } #endif #include <boost/serialization/base_object.hpp> //#include <boost/serialization/utility.hpp> #include <boost/serialization/list.hpp> #include <boost/serialization/is_abstract.hpp> #include <boost/archive/tmpdir.hpp> #include <boost/archive/xml_iarchive.hpp> #include <boost/archive/xml_oarchive.hpp> #include "goal.h" #include "stadium.h" #include "match.h" /** * \brief Fuction to Deserialise a xml-structure to an object structure * \param const Match &m, const char* filename * \return void */ void save_xml(const Match &m, string filename) { // make an archive std::ofstream ofs(filename); assert(ofs.good()); boost::archive::xml_oarchive oa(ofs); oa << BOOST_SERIALIZATION_NVP(m); } /** * \brief Fuction to Serialise an object structure to a xml-structure * \param const Match &m, const char* filename * \return void */ void restore_xml(Match &m, string filename) { // open the archive std::ifstream ifs(filename); assert(ifs.good()); boost::archive::xml_iarchive ia(ifs); // restore the match from the archive ia >> BOOST_SERIALIZATION_NVP(m); } [/cpp][cpp] //xml.h #ifndef _XML_H_INCLUDED_ #define _XML_H_INCLUDED_ #include "goal.h" #include "stadium.h" #include "match.h" using namespace std; void save_xml(const Match &m, string filename); void restore_xml(Match &m, string filename) #endif _XML_H_INCLUDED_ [/cpp]binär:
[cpp] //binary.cpp #include <iomanip> #include <iostream> #include <fstream> #include <string> #include "goal.h" #include "stadium.h" #include "match.h" #include <boost/serialization/base_object.hpp> //#include <boost/serialization/utility.hpp> #include <boost/serialization/list.hpp> #include <boost/serialization/is_abstract.hpp> #include <boost/archive/binary_iarchive> #include <boost/archive/binary_oarchive> //Tracing and Logging module //#include "../include/Logger.h" //#include "../include/Tracer.h" TODO: add Logging/Tracing files for testing using namespace std; /** * \brief Fuction to Deserialise a binary-stream to an object structure * \param const Match &m, const char* filename * \return void */ void save_bin(const Match &m, string filename){ // make an archive std::ofstream ofs(filename); boost::archive::binary_oarchive oa(ofs); oa << m; } /** * \brief Fuction to Serialise an object structure to a binary-stream * \param const Match &m, const char* filename * \return void */ void restore_bin(Match &m, string filename) { // open the archive std::ifstream ifs(filename); boost::archive::binary_iarchive ia(ifs); // restore the match from the archive ia >> m; } [/cpp][cpp] //binary.h #ifndef BINARY_H_INCLUDED_ #define BINARY_H_INCLUDED_ #include "goal.h" #include "stadium.h" #include "match.h" void save_bin(const Match &m, string filename); void restore_bin(Match &m, string filename); #endif BINARY_H_INCLUDED_ [/cpp]Darauf aufbauend habe ich dann Funktionen, die den Ablauf im endgültigen Programm wiederspiegeln:
serialisierung:[cpp] //serialise.cpp #include "serialise.h" #include "binary.h" #include "xml.h" #include "Match.h" #include <stdlib> #include <string> int xml2binary(string xml_file, string &binary_file) { // store the xml-structure in a class Match Match m; restore_xml(&m, xml_file); // save the match as binary stream save_bin(&m, binary_file); } int binary2xml(string binary_file, string &xml_file) { //store the binary-stream in a class Match Match m; restore_bin(&m, binary_file); //save the match as xml-structure save_xml(&m, xml_file); } [/cpp][cpp] //serialise.h #ifndef _SERIALISE_H_INCLUDED_ #define _SERIALISE_H_INCLUDED_ #include "binary.h" #include "xml.h" #include <stdlib> using namespace std; int serialise(string xml_file, string &binary_file); int deserialise(string binary_file, string &xml_file); #endif _SERIALISE_H_INCLUDED_ [/cpp]Und zum Abschluss eine kleine Testfunktion:
[cpp] //main.cpp #include <iomanip> #include <iostream> #include <fstream> #include <string> #include "objstruct.h" #include "binary.h" #include "xml.h" //Tracing and Logging module //#include "../include/Logger.h" //#include "../include/Tracer.h" TODO: add Logging/Tracing files for testing using namespace std; /** * \brief Testfuction to test the (de)serialisation functions * \param const Match &m, const char* filename * \return void */ int main(int argc, char *argv[]) { //TODO: add Tracing & Loggin functions //make goals Goal g1("Kunz", 23, false, 1, true); // make stadium Stadium s1("Irgendwas Stadion", "Berlin", 1000); time_t t1;// = "26.12.08"; // make match Match m1("Deutschland", "Argentinien", t1, g1, s1); std::string xml_file(boost::archive::tmpdir()); xml_file += "../bin/demo.xml"; std::string bin_file(boost::archive::tmpdir()); bin_file += "../bin/demo.xml"; //display the original match1 std::cout << "\nrestored match"; Match::cout << m1; // save the match1 as xml-structure save_xml(m1, filename.c_str()); xml2binary(xml_file, &bin_file); std::string xml_file2(boost::archive::tmpdir()); xml_file2 += "../bin/demo.xml"; binary2xml(bin_file, &xml_file2); delete m1; return 0; } [/cpp]-----------------------------------------------------
Ich hoffe es ist jetzt klar, was ich machen soll.
Vielleich hab ich ja komplett falsch angefangen, aber da ich wirklich nicht sonderlich gut C++ programmieren kann, hab ich mich an die Boost-Beispiele rangehängt und diese für meine Zwecke abgeändert.Ich hoffe ihr könnt mir helfen!
Gruß
Contempt