It was hard to get a working sample for boost::serialization. There are a lot of examples around how you can do this with plain text as output format. But my wish was it to have XML output.
It is important to add the library “boost_serialization” to the linking process. The serialization library of Boost is not only header based! I compiled the listing at the end of this post with:
g++ -std=c++0x -o boostArchive boostArchive.cpp \
-I/usr/local/include -L/usr/local/lib/ -lboost_serialization
This example is creating a XML (“myDataObject.xml”) and will load it afterwards. The format of the XML file is formatted by Boost and has the following format:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="9">
<myDataObject class_id="0" tracking_level="0" version="1">
<px class_id="1" tracking_level="1" version="0" object_id="_0">
<Data class_id="2" tracking_level="1" version="0" object_id="_1">
<name>Christian Benjamin Ries</name>
<id>100</id>
<pi>3.1400001</pi>
<values class_id="3" tracking_level="0" version="0">
<count>2</count>
<item_version>0</item_version>
<item>Hello</item>
<item>World</item>
</values>
</Data>
<city>Berlin</city>
</px>
</myDataObject>
This XML dialect has the format of our classes in the C++ listing below.
/* Christian Benjamin Ries
* www.christianbenjaminries.de
* February 2012
*/
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
// Boost
#include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/scoped_ptr.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/nvp.hpp>
class Data {
public:
std::string name; int id;
float pi; std::vector<std::string> values;
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version) {
// You can store attributes with this macro:
ar & BOOST_SERIALIZATION_NVP(name);
ar & BOOST_SERIALIZATION_NVP(id);
ar & BOOST_SERIALIZATION_NVP(pi);
// You can store attributes as well with a Name-Value-Pair (NVP):
// #include
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ar & make_nvp("name", name);
// ar & make_nvp("id", id);
// ar & make_nvp("pi", pi);
// Following for-loop will produce following without a hierarchy:
// Hello
// World
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//for(auto vIt : values) {
// ar & BOOST_SERIALIZATION_NVP(vIt);
//}
// A better solution is (which will create a hierarchy):
ar & BOOST_SERIALIZATION_NVP(values);
}
};
class MoreData : public Data {
public:
std::string city;
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version) {
using boost::serialization::make_nvp;
// Following line does not work, runtime error: "Invalid XML tag name"
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//ar & BOOST_SERIALIZATION_NVP(boost::serialization::base_object(*this));
//
// It is necessary to define a name, here it is "Data":
ar & make_nvp("Data", boost::serialization::base_object<Data>(*this));
ar & BOOST_SERIALIZATION_NVP(city);
}
};
// This is not working during my tests!
// An export is necessary to automatically create parent classes
// when you like to deserialize base classes with all available
// specializations. On my tests, I got a segmentation fault.
BOOST_CLASS_EXPORT(Data)
BOOST_CLASS_EXPORT(MoreData)
void save() {
boost::shared_ptr<MoreData> myDataObject(new MoreData());
myDataObject->city = "Berlin";
myDataObject->name = "Christian Benjamin Ries";
myDataObject->id = 100;
myDataObject->pi = 3.14;
myDataObject->values.push_back("Hello");
myDataObject->values.push_back("World");
std::ofstream ofs("myDataObject.xml");
boost::archive::xml_oarchive oa(ofs);
oa << BOOST_SERIALIZATION_NVP(myDataObject);
ofs.close();
}
void load() {
std::ifstream ifs("myDataObject.xml");
boost::archive::xml_iarchive ia(ifs);
boost::shared_ptr anotherName;
ia >> BOOST_SERIALIZATION_NVP(anotherName);
ifs.close();
std::cout << "Name: " << anotherName->name << std::endl;
std::cout << "City: " << anotherName->city << std::endl;
}
int main(int argc, char **argv) {
save(); load();
return 0;
}
More information is available: boost::serialization documentation