Russian Qt Forum

Qt => Общие вопросы => Тема начата: Akon от Июль 21, 2012, 10:38



Название: boost::serialization with Qt classes
Отправлено: Akon от Июль 21, 2012, 10:38
Кто-нибудь имеет опыт использования?

По ходу нужно будет писать свободные функции для сериализации Qt типов в boost архивы, или как-то декорировать последние QDataStream'ом.


Название: Re: boost::serialization with Qt classes
Отправлено: DmitryM от Июль 21, 2012, 12:32
Для того, что бы сериализовать Qt классы при помощи boost::serialization нужно перегружать save, load, serialize.
Вот пример того, как сериализую QString.
Код
C++ (Qt)
#ifndef QSTRINGSERIALIZATION_H_
#define QSTRINGSERIALIZATION_H_
 
#include <vector>
#include <QtCore/QString>
#include <QtCore/QVector>
#include <boost/serialization/nvp.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/serialization/vector.hpp>
 
namespace boost
{
 namespace serialization
 {
 
   template<class Archive>
     inline void
     save(Archive& ar, const QString& s, const unsigned int /*version*/)
     {
       std::vector<uint> tmp = s.toUcs4().toStdVector();
       ar << make_nvp("QString2Usc4", tmp);
     }
 
   template<class Archive>
     inline void
     load(Archive& ar, QString& s, const unsigned int /*version*/)
     {
       std::vector<uint> tmp;
       ar >> make_nvp("QString2Usc4", tmp);
       s = QString::fromUcs4(&tmp[0],tmp.size());
     }
 
   template<class Archive>
     inline void
     serialize(Archive& ar, QString& s, const unsigned int file_version)
     {
       boost::serialization::split_free(ar, s, file_version);
     }
 
 } // namespace serialization
} // namespace boost
 
#endif /* QSTRINGSERIALIZATION_H_ */
 


Название: Re: boost::serialization with Qt classes
Отправлено: Akon от Июль 21, 2012, 14:56
Спасибо. А не знаете ли случаем готовых реализаций? Ведь каждый, кто столкнулся с такой проблемой, будет делать такие реализации (если не найдет готовые).


Название: Re: boost::serialization with Qt classes
Отправлено: DmitryM от Июль 21, 2012, 16:21
Готовых не нашел. Да собственно и не очень нужно. В случае c QString у меня не получилось работать с wchar_t и std::wstring(выдовал ошибку линковки в Windows с MinGW).
Для остальных случаев можно использовать паттерн хранитель(Memento) который сериализуешь, а при помощи BOOST_SERIALIZATION_SPLIT_MEMBER() разбиваешь метод serialize на load и save.


Название: Re: boost::serialization with Qt classes
Отправлено: Akon от Июль 21, 2012, 17:46
Цитировать
В случае c QString у меня не получилось работать с wchar_t и std::wstring(выдовал ошибку линковки в Windows с MinGW).
Я сериализовал QString через QString::toStdString. Может для wchar_t использовать QString::toStdWString()?

Да, с мементо понятно. Но всякие QList<T>, QHostAddress и другие типы нужно поддерживать (load/save/serialize) для удобного использования из мементо.

Собственно, сейчас я пошел по пути наименьшего сопротивления и свел необходимые мне в данный момент Qt типы (строки и контейнеры) к поддерживаемым boost::serialization (т.е. к STL-ным типам).

Полное решение - все сериализуемые QDataStream'ом Qt типы нужно поддержать для boost::serialization.


Название: Re: boost::serialization with Qt classes
Отправлено: DmitryM от Июль 21, 2012, 18:25
Цитировать
В случае c QString у меня не получилось работать с wchar_t и std::wstring(выдовал ошибку линковки в Windows с MinGW).
Я сериализовал QString через QString::toStdString. Может для wchar_t использовать QString::toStdWString()?
Цитировать
The QString class provides a Unicode character string
Следовательно при использование QString::toStdString могут выплыть всякие нехорошие вещи.
В случае с wchar_t то в разных системах он имеет разный размер, а проблемы появились при использование  boost::archive::xml_woarchive и MinGW.