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

标签 boost boost-serialization

我正在使用 boost::serialization在我的项目中。该项目很大,并且在多个地方序列化了我的对象。根据documentation here ,我应该用两个单独的步骤导出我的类。

  • BOOST_EXPORT_KEY().h文件,女巫包含声明。
  • 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不管用。但这真的很奇怪,因为:
  • 如果我注册实现是 main.cpphier.cpp ,它在链接时发出重复的定义。 表示在 hier.cpp 中注册没问题,并且暴露在链接器可见性中。 ,否则不会出现重复定义错误。
  • 如果我仅在 main.cpp 中注册实现,运行正常。

  • 在那种情况下,我真的很困惑。任何意见和建议表示赞赏。提前致谢。

    最佳答案

    调用前BOOST_CLASS_EXPORT_*您应该包括要使用的文件。然后,makro 为 header 添加特定的序列化函数。

    这意味着您应该在 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:
    我不知道这是否解决了您的问题,但我认为这可能会造成一些麻烦。我认为值得一试。

    关于Boost 序列化多态寄存器(导出)不能跨文件工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7875107/

    相关文章:

    c++ - 反序列化构造函数无法正确读取数据

    c++ - 每次继承时都需要boost::serialization::base_object吗?

    c++ - Boost asio, shared_from_this() error R6010, and async_read() eof

    c++ - boost_multi 数组太大? bad_alloc 错误

    c++ - 使用信号处理程序触发事件时,如何让 boost.msm 正确更改状态?

    c++ - 使用 boost::geometry::within 编译错误

    c++ - Boost.序列化警告

    c++ - Boost::serialization 和 boost::mpi 通过基类指针广播派生类

    c++ - BOOST asio 是否支持 eventfd?像 epoll

    c++ - 带 Boost 的多态序列化