Ускоренная полимеризация регистра сериализации (экспорт) не работает между файлами - PullRequest
3 голосов
/ 24 октября 2011

Я использую boost::serialization в моем проекте.Проект большой, и сериализует мои объекты в нескольких местах.Согласно документации здесь , я должен экспортировать свой класс с двумя разделенными шагами.

  1. BOOST_EXPORT_KEY() в файле .h, ведьма содержит объявление.
  2. BOOST_EXPOET_IMPLEMENT() в файле .cpp, в котором содержится экземпляр (определение) экспорта.

hier.h иерархия классов, в иерархии 3 класса.

/*
B <---+--- D1
      |
      +--- D2
*/

#include <boost/serialization/base_object.hpp>                                                                                                                                                                 

class B {                                                                                                                                                                                                      
public:                                                                                                                                                                                                        
    virtual ~B() {}                                                                                                                                                                                            
    template < typename Ar >                                                                                                                                                                                   
    void serialize(Ar& ar, const int) {                                                                                                                                                                        
    }                                                                                                                                                                                                          
} ;                                                                                                                                                                                                            

class D1 : public B {                                                                                                                                                                                          
public:                                                                                                                                                                                                        
    virtual ~D1() {}                                                                                                                                                                                           
    template < typename Ar > void serialize(Ar& ar, const int) {                                                                                                                                               
        boost::serialization::base_object<B>(*this);                                                                                                                                                           
    }                                                                                                                                                                                                          
} ;                                                                                                                                                                                                            

class D2 : public B {                                                                                                                                                                                          
public:                                                                                                                                                                                                        
    template < typename Ar > void serialize(Ar& ar, const int) {                                                                                                                                               
        boost::serialization::base_object<B>(*this);                                                                                                                                                           
    }                                                                                                                                                                                                          
    virtual ~D2() {}                                                                                                                                                                                           
} ;                                                                                                                                                                                                            

#include <boost/serialization/export.hpp>                                                                                                                                                                      

BOOST_CLASS_EXPORT_KEY(B);                                                                                                                                                                                     
BOOST_CLASS_EXPORT_KEY(D1);                                                                                                                                                                                    
BOOST_CLASS_EXPORT_KEY(D2);

И hier.cpp содержит реализацию:

#include <boost/serialization/export.hpp>
#include "hier.h"

BOOST_CLASS_EXPORT_IMPLEMENT(D1);
BOOST_CLASS_EXPORT_IMPLEMENT(D2);

И main.cpp используют сериализацию:

#include <iostream>                                                                                                                                                                                            
#include <sstream>                                                                                                                                                                                             
#include <boost/archive/text_iarchive.hpp>                                                                                                                                                                     
#include <boost/archive/text_oarchive.hpp>                                                                                                                                                                     
#include <boost/serialization/export.hpp>                                                                                                                                                                      
#include "hier.h"                                                                                                                                                                                              

int main(int argc, char* argv[])                                                                                                                                                                               
{                                                                                                                                                                                                              
    B* d1 = new D1();                                                                                                                                                                                          
    B* d2 = new D2();                                                                                                                                                                                          
    std::ostringstream os;                                                                                                                                                                                     
    boost::archive::text_oarchive oa (os);                                                                                                                                                                     
    oa & d1 & d2;                                                                                                                                                                                              
}

Он скомпилирован без проблем, но запустить его будетпричина:

terminate called after throwing an instance of 'boost::archive::archive_exception'
  what():  unregistered class - derived class not registered or exported

Это означает, что производный класс не зарегистрирован, означает, что регистрация в hier.cpp не работает.Но это действительно странно, потому что:

  1. Если я регистрирую, что реализация - это main.cpp и hier.cpp, при компоновке выдается дублированное определение. Означает, что регистрация в hier.cpp в порядке и доступна для просмотра компоновщиками. , иначе не будет дублирующейся ошибки определения.

  2. Если я регистрирую только реализациюв main.cpp он работает нормально.

Я действительно запутался в этой ситуации.Любые комментарии и предложения приветствуются.Заранее спасибо.

1 Ответ

8 голосов
/ 30 января 2012

Перед вызовом BOOST_CLASS_EXPORT_* вы должны включить архивы, которые вы хотите использовать. Затем макро добавляет специальные функции сериализации для заголовков.

Это означает, что вы должны изменить свой код в hier.cpp на следующее:

#include <boost/serialization/export.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include "hier.h"

BOOST_CLASS_EXPORT_IMPLEMENT(D1);
BOOST_CLASS_EXPORT_IMPLEMENT(D2);

Код в hier.h изменяется соответственно:

#include <boost/serialization/export.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>

BOOST_CLASS_EXPORT_KEY(B);
BOOST_CLASS_EXPORT_KEY(D1);
BOOST_CLASS_EXPORT_KEY(D2);

Источники:
Документация для ускоренной сериализации

PS:
Я не знаю, решает ли это вашу проблему, но я думаю, что это может вызвать некоторые проблемы. Я думаю, стоит попробовать.

...