Доброговремени суток всем!
Возникла такая проблема:
есть несколько класов
// include headers that implement a archive in simple text format
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
// включаем, чтобы сериализация работала с векторами
#include <boost/serialization/vector.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/shared_ptr_132.hpp>
#include <boost/serialization/list.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/strong_typedef.hpp>
//#include <boost/serialization/map.hpp>
//#include <boost/serialization/variant.hpp>
// включаем, чтобы нормально проходила сериализация XML
#include <boost/serialization/nvp.hpp>
#include <map>
#include "boost/variant.hpp"
#include <boost/fusion/container/list.hpp>
#include "boost/shared_ptr.hpp"
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
using namespace boost;
typedef boost::variant<unsigned int,double,wstring> SCADAVariant;
class Item;
class Set;
class Configuration;
typedef list <boost::shared_ptr<Item>> pItemList;
class Item
{
wstring fIdent; //Идентификатор строковый
public:
Item();
Item(wstring Ident);
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar,const unsigned int vertion)
{
ar & BOOST_SERIALIZATION_NVP(fIdent);
}
};
class Set : public Item
{
friend Item;
pItemList Items; //Элементы множества
public:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar,const unsigned int vertion)
{
ar & BOOST_SERIALIZATION_NVP(Items); //не сериалезует!
}
};
//Главный класс конфигурации. Обеспечивает хранение и сериализацию
template<typename TIArch, typename TOArch, typename TClass>
void TestArch(const std::string & file, int flags, const TClass & cont)
{
{ // Сериализуем
std::ofstream ofs(file.c_str(), std::ios::out|flags);
TOArch oa(ofs);
// make_nvp создаёт пару имя-значение, которая отразится в XML
// если не используем XML архив, то можно пару не создавать
oa << boost::serialization::make_nvp("Test_Object", cont);
}
TClass newg;
{ // Десериализуем
std::ifstream ifs(file.c_str(), std::ios::in|flags);
TIArch ia(ifs);
ia >> boost::serialization::make_nvp("Test_Object",newg);
}
{ // Еще раз сериализуем, чтобы потом сравнить результаты двух сериализаций
// и убедиться, что десериализациия прошла корректно
std::ofstream ofs((file+".tmp").c_str(), std::ios::out|flags);
TOArch oa(ofs);
oa << boost::serialization::make_nvp("Test_Object", cont);
}
}
class Configuration
{
friend Item;
Set root;
public:
Configuration(); //Инициализация
~Configuration();
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar,const unsigned int vertion)
{
ar & BOOST_SERIALIZATION_NVP(root);
}
};
С этим вроде разобрался: оказалось я пытался сериализовать wstring fIdent а буст не поддерживает сериализацую wstring.
Теперь вопрос как Сериализовать wstrinig ?
Буст поддерживает сериализацию wstring. Вроде бы он для этого должен быть скомпилен с ICU, хотя конкретно насчёт библиотеки сериализации точно не могу сказать, может, ей просто опцию какую-то надо указать при сборке. У меня буст собран с ICU и все юникодовские функции работают. Но не все комилеры поддерживают юникод. Например, mingw его не поддерживает.
Юзай wofstream и binary_woarchive, если компилятор позволяет. Если нет - то переводи в string и сериализуй как string, а потом обратно. Либо как бинарный поток.
с wstring я разобрался в опциях прроекта переходим: Configuration properties -> C++ -> Langages->Treast wchar_t as Built-in type = <inherit from parent or project defaults>
и усё работает )))))))
теперь осталось только одно понять как сериализовать конструкцию типа
List<shared_ptr<Item>> pItemList , где Item - класс, а проще как сериализовать список умных указателей на класс?
Iron Bug - спасибо за совет)
я не совсем понимаю, нафига сериализовать такие сложные аггломераты, но люди пишут, что даже такой изврат возможен.
учимся пользоваться гуглом и в поиске по строке "boost serialization shared_ptr" находим вот это:
http://www.boost.org/doc/libs/1_42_0/libs/serialization/doc/shared_ptr.html
дальше читать всё это и усваивать.
но я бы не стала связываться с такими наворотами. да и автор статьи не рекомендует этого делать, ибо даже после всей этой возни остаются некоторые нерешённые вопросы.
а вообще, зачем тебе столько наворотов для сохранения в файл? может, всё куда проще решается, нежели чем через такие пампасы?
конечно, если хочешь, ковыряй статью, пиши кучу кода. это не возбраняется. но что-то мне подсказывает, что есть куда более простое решение для задачи, которую ты пытаешься решить.
эо пример класса конфигурации есть несколько деревьев Item может находиться сразу в нескольких деревьяк(у нас они называются измерения)
я думал сначало сохранять всё в поток но понял что пытаюсь написать велосипед тк в бусте сериализация позволяет сохранять в бинарник в текст и в поток)
вот и думаю как это сделать))) по сути мне нужно сохранить список всех итемов и указателей а при загрузке востановить всё это дело в пямяти)
имхо, в такой ситуации лучше бы сделать синглтон, который работает непосредственно с конфигурацией, а в нём реализовать список элементов и сквозные массивы указателей на них (boost::intrusive).
ведь конфигурация - это обычно не то, что постоянно меняется и меняется неожиданно из разных мест.
городить сериализацию тэмплейтов - дело неблагодарное. а главное - из пушки по воробьям
Как всегда всё оказалось проще чем я дкмал)))
Почитав кучу доки я в boost нашол макрос BOOST_SERIALIZATION_BASE_OBJECT_NVP
мне нужно было заюзать макрос ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Items) и вуаля всё заработало)))
Насчёт стрельбы по воробьям из пушки: у буста она сильно точно стреляет и велосипеды у них хорошие , много функциональные))))
на этом тему можно считать закрытой))))
Iron Bug - спасибо за участие
Вышел интересный Баг в сериализации wstring : у меня boost отказывается сериализовать wstring который содержит русские буквы.....
Может кто сталкивался с добной проблеммой?
проверь локали на машине, если это линюкс. может банально не быть нужной локали. проверь опции юникода для компилера.
если не оно, то пиши пример, как конкретно ты сериализуешь и чем собираешь.
windows 7 , VS2008 + QT 4.6.1 + boost 1.38))
до этого некто не догодался тэстировать с русскими буквами))
код чуть позже скину)
да нет, у меня прекрасно всё получалось и с русскими буквами. просто надо поднимать старые проекты, а без кода нечего обсуждать.
а буст староват, мягко говоря. лучше бы обновить до 41 или 44 (наиболее свежие и наименее глючные версии).
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)