Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Сериализация списка указателей в boost
Форум на CrossPlatform.RU > Библиотеки > boost
madnessw
Доброговремени суток всем!
Возникла такая проблема:
есть несколько класов


      
// 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);
            }

        };

проблема вследующем нополучается сериализовать стуктуру типа pItemList Items, она объявлена как typedef list <boost::shared_ptr<Item>>pItemList.
Посуте я пытаюсь сериализовать список умных указателей на что получаю:

Error 7 error LNK2019: unresolved external symbol "protected: void __thiscall boost::archive::basic_binary_iprimitive<class boost::archive::binary_iarchive,char,struct std::char_traits<char> >::load(class std::basic_string<unsigned short,struct std::char_traits<unsigned short>,class std::allocator<unsigned short> > &)" (?load@?$basic_binary_iprimitive@Vbinary_iarchive@archive@boost@@DU?$char_traits@D@std@@@archive@boost@@IAEXAAV?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@@Z) referenced in function "public: static void __cdecl boost::archive::load_access::load_primitive<class boost::archive::binary_iarchive,class std::basic_string<unsigned short,struct std::char_traits<unsigned short>,class std::allocator<unsigned short> > >(class boost::archive::binary_iarchive &,class std::basic_string<unsigned short,struct std::char_traits<unsigned short>,class std::allocator<unsigned short> > &)" (??$load_primitive@Vbinary_iarchive@archive@boost@@V?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@@load_access@archive@boost@@SAXAAVbinary_iarchive@12@AA
V?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@@Z)
вот и не пойму где ошибка может кто сталкивался с подобным?
madnessw
С этим вроде разобрался: оказалось я пытался сериализовать wstring fIdent а буст не поддерживает сериализацую wstring.
Теперь вопрос как Сериализовать wstrinig ?
Iron Bug
Буст поддерживает сериализацию wstring. Вроде бы он для этого должен быть скомпилен с ICU, хотя конкретно насчёт библиотеки сериализации точно не могу сказать, может, ей просто опцию какую-то надо указать при сборке. У меня буст собран с ICU и все юникодовские функции работают. Но не все комилеры поддерживают юникод. Например, mingw его не поддерживает.
Юзай wofstream и binary_woarchive, если компилятор позволяет. Если нет - то переводи в string и сериализуй как string, а потом обратно. Либо как бинарный поток.
madnessw
с 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 - спасибо за совет)
Iron Bug
я не совсем понимаю, нафига сериализовать такие сложные аггломераты, но люди пишут, что даже такой изврат возможен.
учимся пользоваться гуглом и в поиске по строке "boost serialization shared_ptr" находим вот это:
http://www.boost.org/doc/libs/1_42_0/libs/...shared_ptr.html

дальше читать всё это и усваивать.
но я бы не стала связываться с такими наворотами. да и автор статьи не рекомендует этого делать, ибо даже после всей этой возни остаются некоторые нерешённые вопросы.
а вообще, зачем тебе столько наворотов для сохранения в файл? может, всё куда проще решается, нежели чем через такие пампасы?
конечно, если хочешь, ковыряй статью, пиши кучу кода. это не возбраняется. но что-то мне подсказывает, что есть куда более простое решение для задачи, которую ты пытаешься решить.
madnessw
эо пример класса конфигурации есть несколько деревьев Item может находиться сразу в нескольких деревьяк(у нас они называются измерения)
я думал сначало сохранять всё в поток но понял что пытаюсь написать велосипед тк в бусте сериализация позволяет сохранять в бинарник в текст и в поток)
вот и думаю как это сделать))) по сути мне нужно сохранить список всех итемов и указателей а при загрузке востановить всё это дело в пямяти)
Iron Bug
имхо, в такой ситуации лучше бы сделать синглтон, который работает непосредственно с конфигурацией, а в нём реализовать список элементов и сквозные массивы указателей на них (boost::intrusive).
ведь конфигурация - это обычно не то, что постоянно меняется и меняется неожиданно из разных мест.
городить сериализацию тэмплейтов - дело неблагодарное. а главное - из пушки по воробьям :)
madnessw
Как всегда всё оказалось проще чем я дкмал)))
Почитав кучу доки я в boost нашол макрос BOOST_SERIALIZATION_BASE_OBJECT_NVP
мне нужно было заюзать макрос ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Items) и вуаля всё заработало)))

Насчёт стрельбы по воробьям из пушки: у буста она сильно точно стреляет и велосипеды у них хорошие , много функциональные))))

на этом тему можно считать закрытой))))
Iron Bug - спасибо за участие
madnessw
Вышел интересный Баг в сериализации wstring : у меня boost отказывается сериализовать wstring который содержит русские буквы.....

Может кто сталкивался с добной проблеммой?
Iron Bug
проверь локали на машине, если это линюкс. может банально не быть нужной локали. проверь опции юникода для компилера.
если не оно, то пиши пример, как конкретно ты сериализуешь и чем собираешь.
madnessw
windows 7 , VS2008 + QT 4.6.1 + boost 1.38))

до этого некто не догодался тэстировать с русскими буквами))
код чуть позже скину)
Iron Bug
да нет, у меня прекрасно всё получалось и с русскими буквами. просто надо поднимать старые проекты, а без кода нечего обсуждать.
а буст староват, мягко говоря. лучше бы обновить до 41 или 44 (наиболее свежие и наименее глючные версии).
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.