2012-02-08 6 views
6

DLL内のクラス構造を外部的にシリアライズする(作業中の)例を探しています。現在、私はその事例を見つけることができません。 Boostのドキュメントには、いくつかのマクロが記載されているだけです。フォーラムやニュースグループは、ソリューションに関する特定の問題について議論しています。クラスのシリアライゼーションをDLLに入れよう

私は次のようなクラス構造を(外部的に)直列化する例を求めています。クラスコードに加えて、シリアル化のためのコードをいくつか追加しました(これは動作しません。エラーメッセージの下部を参照してください)。

class Foo 
{ 
public: 
    Foo() { number_ = 0; } 
    virtual ~Foo() {} 

    int getNumber() { return number_; } 
    void setNumber(int var) { number_ = var; } 
private: 
    int number_; 
}; 

class Bar : public Foo 
{ 
public: 
    Bar() { doubleNumber_ = 0.0; } 
    virtual ~Bar() {} 

    double getDouble() { return doubleNumber_; } 
    void setDouble(double var) { doubleNumber_ = var; } 

private: 
    double doubleNumber_; 
}; 

私がこれまで持っているものすべてが、このようなコードです:

serializeFoo.h

#ifndef _SERIALIZE_FOO_H_ 
#define _SERIALIZE_FOO_H_ 

#include "Foo.h" 
#include <boost/serialization/split_free.hpp> 
#include <boost/serialization/version.hpp> 

namespace boost { 
namespace serialization { 

template <typename Archive> 
void save(Archive& ar, const Foo& object, const unsigned int version) 
{ 
    ar << object.getNumber(); 
} 

template <typename Archive> 
void load(Archive& ar, Foo& object, const unsigned int version) 
{ 
    int number; 
    ar >> number; 
    object.setNumber(number); 
} 

}} //namespace brackets 

BOOST_SERIALIZATION_SPLIT_FREE(Foo) 

#include <boost/archive/text_oarchive.hpp> 
#include <boost/archive/text_iarchive.hpp> 
#include <boost/serialization/export.hpp> 
BOOST_CLASS_EXPORT_KEY(Foo) 

#endif //_SERIALIZE_FOO_H_ 

serializeFoo.cpp

#include "serializeFoo.h" 
BOOST_CLASS_EXPORT_IMPLEMENT(Foo) 

seriali zeBar.h

#ifndef _SERIALIZE_BAR_H_ 
#define _SERIALIZE_BAR_H_ 

#include "Bar.h" 
#include <boost/serialization/split_free.hpp> 
#include <boost/serialization/version.hpp> 

namespace boost { 
namespace serialization { 

template <typename Archive> 
void save(Archive& ar, const Bar& object, const unsigned int version) 
{ 
    ar << base_object<Foo>(object); 
    ar << object.getDouble(); 
} 

template <typename Archive> 
void load(Archive& ar, Bar& object, const unsigned int version) 
{ 
    double doubleNumber; 
    ar >> doubleNumber; 
    object.setDouble(doubleNumber); 
} 

}} //namespace brackets 

BOOST_SERIALIZATION_SPLIT_FREE(Bar) 

#include <boost/archive/text_oarchive.hpp> 
#include <boost/archive/text_iarchive.hpp> 
#include <boost/serialization/export.hpp> 
BOOST_CLASS_EXPORT_KEY(Bar) 

#endif //_SERIALIZE_BAR_H_ 

serializeBar.cpp

#include "serializeBar.h" 
BOOST_CLASS_EXPORT_IMPLEMENT(Bar) 

シリアライズ・コードがDLLに入り、クラスfooとbarを使用して別のプロジェクトで使用する必要があります。すべてがうまくコンパイルされますが、実行時にメッセージが表示されます
unregistered class - derived class not registered or exported

私は間違ったマクロを使用しましたか?マクロが欠けていますか?上記のコードは正しいのですか、または何らかの構造的なエラーがありますか?おそらく、これは他の多くの人にとっても役に立つかもしれませんが、私はDLLへのクラスのシリアライゼーションを非常にエキゾチックなものにしているとは思っていません...

+0

私がBoost-docsで見たものは、 'BOOST_SERIALIZATION_FACTORY_0(Foo)'でしたが、それが必要かどうかわかりません。リンク:http://www.boost.org/doc/libs/1_37_0/libs/serialization/doc/special.html#dlls – MOnsDaR

+0

もしあなたが気分が良くなるなら、私はそれがうまく動いているプロジェクトを持っていますヘッダファイルの一番上にアーカイブヘッダーを含めるという点を除いて、コードはあなたのものとかなり同じように見えます。 P.S.それは技術的に '.so'ではなく、' .dll'ではなく、違いを生むべきではありません... – TC1

+0

私は "Shared lib"を最初に書くつもりでしたが、これは現在この特定のタイプの共有ライブラリの問題です。 – MOnsDaR

答えて

1

シリアライズしたいすべてのクラスを登録するには、この質問を頼まれた3年後。私は最終的にそれを解決するための回避策を見つけました。上記の例では、

  • BarFooのサブクラスであるため、登録/エクスポートする必要があります。
  • serializeFoo.cppは、登録/エクスポートするGUIDテンプレートクラスをインスタンス化しますFoo;
  • serializeBar.cppは、登録/エクスポートするGUIDテンプレートクラスをインスタンス化しますBar;
  • クラスキーをエクスポートする前にすべての必要なアーカイブタイプを含めるルールは尊重されます。
  • 両方の翻訳単位がリンクされてDLLが作成されます。あなたはBarオブジェクトを指すポインタFoo*をシリアライズしようとしている間、私は、あなたのexeファイルに想定し

は、あなたが「未登録クラスblahblah」エラーを得ました。 Boost.Serializationは、の前に、クラスBarのGUIDを正しく生成しないため、serialize関数が呼び出されるからです。

なぜこのようなことが起こるのかわかりませんが、GUIDが怠け者の方法で生成されているように見えます。翻訳単位serializeBar.cppのシンボルが1つもない場合、その変換で定義されているインスタンス化/ユニットが実行されます。これには、クラス登録/エクスポートのBarが含まれます。

ことを証明するために、あなたはFoo*のために任意のシリアライズ関数を呼び出す前に、(例えばserializeBar.cppで実装ダミー関数を呼び出すことによって)serializeBar.cppに(ダミー)記号を使用しようとすることができます。問題は消えるはずです。

希望します。

+0

3年...いまいましい! :D – MOnsDaR

0

難しいことがあります。間違って行く。 boost serializationのテストコードをダウンロードすることをお勧めします(www.boost.org/doc/libs/1_48_0/libs/serialization/test/)。 Ah、A.cpp、dll_a.cpp(基本的にはあなたのシナリオをテストしています)のテストケースを見て、ブーストテストシステムの外で動作させようとします。ビルド環境を使用し、コンパイラ/リンカオプションをあなたのツールセットのためのブーストテストスイートのそれらと一致します。

正直なところ、私見、いくつかの点で、シリアライズ/ Oの外部ツールワット++ビルドモデルC純粋で確実に可能であるものの境界線を横切る後押し...

1

シリアライズライブラリと一緒に配布テストスイートとデモ実証正確にこの施設。だから最初にそれが動作することを確認します。あなたの例をそれと比較してください。

ロバート・ラミー

「正直なところ、私見では、いくつかの点で、シリアライズ/ Oの外部ツールワット++ビルドモデルC純粋で確実に可能であるものの境界線を横切るブースト...」

hmmmmmm - そうそれは可能な限り境界線を越えますか?あなたは精神でかなり正しいです。そのようなパッケージがブーストに受け入れられるために必要と考えられるすべてを実装するために大きな努力が費やされました。

RR

0

使用BOOST_CLASS_EXPORTあなたは、私は最近、同様の問題に遭遇した

関連する問題