By default boost::serialization library can not serialize a directly given QString variable, so you need an extra Serializer implementation for your serialization and deserialization requirements.
When you try to serialize a QString variable directly by using boost::serialization library, compiler gives errors about missing serialize method as follows :
error: 'class QString' has no member named 'serialize'
In order to use boost::serialization library in your applications, it is required to have libboost-all-dev library on your OS which contains libboost-serialization-dev. Following terminal command installs required boost libraries on linux OS :
$ sudo apt-get install libboost-all-dev
After installing boost serialization library, you can start including related header files into your application.
Following sample project created by qt creator and contains following files :
1-BoostSerializeQString.pro
2-QStringSerializer.h
3-User.h
4-main.cpp
BoostSerializeQString.pro file contains project configuration.
QT += core TARGET = BoostSerializeQString CONFIG += console CONFIG -= app_bundle TEMPLATE = app LIBS += -lboost_serialization SOURCES += main.cpp HEADERS += QStringSerializer.h \ User.h
boost_serialization library is included into this Qt Project by adding "LIBS += -lboost_serialization" line.
In this example User class contains two QString instance variables to serialize and deserialize. When saving and loading User class it is required to save and load QString variable state properly. Also, User class has an intrusive serialize function. For User class case, the serialize function is implemented as a member of the class.
#ifndef USER_H #define USER_H class User { public: User() {} User(const QString &name, const QString &surname) { this->name = name; this->surname = surname; } QString getName() { return name; } QString getSurname() { return surname; } private: QString name; QString surname; friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned int version) { // serialize deserialize QString instance variables ar & BOOST_SERIALIZATION_NVP(name); ar & BOOST_SERIALIZATION_NVP(surname); } }; #endif // USER_H
QStringSerializer.h file contains save and load functions which are going to be invoked during serialization and deserialization process of QString instance variables.
By declaring non-intrusive serialization mechanism we were able to implement serialization for QString without changing its original class definition.
boost::serialization is able to work on std::string type correctly, so it is required to retrieve std::string value of QString for serialization. And also for the reverse operation it is required to construct QString from loaded std::string value.
QString has got both toStdString and fromStdString functions to achieve these requirements.
Inside serialize and deserialize functions different statements are executed so it is required to implement save and load functions separately.
Depending on the type of the archieve used for saving or loading current QString variable, save or load function is invoked.
#ifndef QSTRINGSERIALIZER_H #define QSTRINGSERIALIZER_H namespace boost { namespace serialization { template<class Archive> void save( Archive & ar, const QString& qStringParam, const unsigned int ) { // save class member variables std::string stdString = qStringParam.toStdString(); ar & BOOST_SERIALIZATION_NVP(stdString); } template<class Archive> void load( Archive & ar, QString& qStringParam, const unsigned int ) { // load class member variables std::string stdString; ar & BOOST_SERIALIZATION_NVP(stdString); qStringParam = qStringParam.fromStdString(stdString); } template<class Archive> void serialize(Archive & ar, QString & t, const unsigned int file_version) { split_free(ar, t, file_version); } } // namespace serialization } // namespace boost #endif // QSTRINGSERIALIZER_H
main method in main.cpp file contains two code blocks which are respectively used for serialization and deserialization of User object with QString instance variables or states. After reconstructing User object, QString instance variables name and surname are initialized with the original values as serialized.
#include <boost/archive/xml_iarchive.hpp> #include <boost/archive/xml_oarchive.hpp> #include <boost/serialization/string.hpp> #include <boost/serialization/nvp.hpp> #include <QString> #include <fstream> #include <iostream> #include "User.h" #include "QStringSerializer.h" using namespace std; int main() { { // Initialize User object to serialize with data User user("userName","userSurname"); std::ofstream ofs("stateInfoFile.xml"); boost::archive::xml_oarchive oa(ofs); // write class instance to archive oa & BOOST_SERIALIZATION_NVP(user); } { User user; std::ifstream ifs("stateInfoFile.xml"); boost::archive::xml_iarchive ia(ifs); // read class instance back from archive ia & BOOST_SERIALIZATION_NVP(user); std::cout << "Name : " << user.getName().toStdString() << std::endl; std::cout << "Surname : " << user.getSurname().toStdString() << std::endl; } }
User object state is saved into stateInfoFile.xml file and loaded back from the same xml file again for object reconstruction. stateInfoFile.xml file is an xml file and its content is as follows :
No comments:
Post a Comment