5

私はboost::serialization自分のプロジェクトで使用しています。プロジェクトは大規模で、オブジェクトをいくつかの場所でシリアル化します。ここのドキュメントによると、2つの別々のステップでクラスをエクスポートする必要があります。

  1. BOOST_EXPORT_KEY().hファイルでは、witchに宣言が含まれています。
  2. BOOST_EXPOET_IMPLEMENT()ファイルで.cppは、witchにはエクスポートのインスタンス化(定義)が含まれています。

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

そして、ahier.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、リンク中に重複した定義が発行されます。での登録がOKであり、リンカーの可視性に公開されていることを意味します。hier.cpp、それ以外の場合、重複した定義エラーは発生しません。

  2. にのみ実装を登録すればmain.cppOKです。

私はその状況で本当に混乱しています。コメントや提案をいただければ幸いです。前もって感謝します。

4

1 に答える 1

10

Before calling BOOST_CLASS_EXPORT_* you should include the archives which you want to use. The makro then adds specific serialize-functions for the headers.

This means you should change your code in hier.cpp to the following:

#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);

The code in hier.h changes accordingly:

#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);

Sources:
Boost Serializsation Documentation

PS:
I do not know if this is solving your problem, but I think it could be causing some trouble. I think its worth a try.

于 2012-01-30T07:05:00.090 に答える