Boost序列化多态寄存器(导出)不能跨文件工作

时间:2011-10-24 11:45:56

标签: boost boost-serialization

我在我的项目中使用boost::serialization。该项目很大,并在几个地方序列化我的对象。根据{{​​3}},我应该通过两个单独的步骤导出我的课程。

    {li> BOOST_EXPORT_KEY().h文件中,包含声明。 在BOOST_EXPOET_IMPLEMENT()文件中的
  1. .cpp,包含导出的实例化(定义)。
  2. 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.cpphier.cpp,它会在链接时发出重复的定义。 表示hier.cpp中的注册正常,并且会显示在链接器可见性中。,否则将不会出现重复的定义错误。

    2. 如果我只在main.cpp注册实施,则运行正常。

    3. 在这种情况下,我真的很困惑。任何评论和建议表示赞赏。提前致谢。

1 个答案:

答案 0 :(得分:8)

在致电BOOST_CLASS_EXPORT_*之前,您应该包含要使用的档案。然后makro为标题添加特定的序列化函数。

这意味着您应该将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);

来源:
Boost Serializsation Documentation

PS:
我不知道这是否解决了你的问题,但我认为这可能会造成一些麻烦。我认为值得一试。