7

DLLのクラス構造を外部でシリアル化するための(実用的な)例を探しています。現在、その例を見つけることができません。Boostのドキュメントには、いくつかのマクロが記載されているだけであり、フォーラムやニュースグループは、ソリューションに関する特定の問題について話し合っているだけです。

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

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 )

serializeBar.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に入れることは非常にエキゾチックではないと思います...

4

4 に答える 4

2

この質問が出されてから3年後、私は最近同様の問題に遭遇しました。私はついにそれを解決するための回避策を見つけました。上記の例では。

  • BarはのサブクラスでFooあるため、登録/エクスポートする必要があります。
  • serializeFoo.cpp登録/エクスポートするGUIDテンプレートクラスをインスタンス化しますFoo;
  • serializeBar.cpp登録/エクスポートするGUIDテンプレートクラスをインスタンス化しますBar;
  • クラスキーをエクスポートする前に必要なすべてのアーカイブタイプを含めるためのルールが尊重されます。
  • 両方の変換ユニットがリンクされてDLLが作成されます。

あなたのexeファイルでFoo*、オブジェクトを指すポインタをシリアル化しようとしているBarときに、「unregisteredclassblahblah」エラーが発生したと思います。これは、Boost.Serializationが、serialize関数が呼び出されるBar 前にクラスのGUIDを適切に生成しないためです。

これが発生する理由はわかりませんが、GUIDが遅延して生成されているようです-変換ユニットのシンボルserializeBar.cppが使用されていない場合、その変換ユニットで定義されているインスタンス化/初期化コードは実行されません- -これには、のクラス登録/エクスポートが含まれBarます。

それを証明するために、のシリアル化関数を呼び出す前に、で(ダミー)シンボルを使用してみることができますserializeBar.cpp(たとえば、に実装されているダミー関数を呼び出すことによって) 。問題は消えるはずです。serializeBar.cppFoo*

それが役に立てば幸い。

于 2015-03-12T14:20:42.383 に答える
1

シリアル化ライブラリとともに配布されるテストスイートとデモは、まさにこの機能を示しています。したがって、最初にそれが機能することを確認してください。次に、例をそれに比較します。

ロバート・ラミー

「正直なところ、IMHOは、ある時点で、Boost Serializationは、外部ツールを使用しない純粋なc++ビルドモデルで確実に可能なことの境界を越えています...」

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

RR

于 2012-07-07T01:44:01.867 に答える
0

わかりにくい...物事がうまくいかない可能性はたくさんあります。ブーストシリアル化のテストコードをダウンロードすることをお勧めします(www.boost.org/doc/libs/1_48_0/libs/serialization/test/)。Ah、A.cpp、dll_a.cpp(基本的にシナリオをテストします)の周りのテストケースを見て、ブーストテストシステムの外で動作するようにしてください:ビルド環境を使用し、コンパイラ/リンカーオプションを次のように変更してみてくださいツールセットのブーストテストスイートのものと一致します。

正直なところ、IMHOは、ある時点で、Boost Serializationは、外部ツールを使用しない純粋なc++ビルドモデルで確実に可能なことの境界を越えています...

于 2012-02-15T07:20:02.900 に答える
0

BOOST_CLASS_EXPORTシリアル化するすべてのクラスを登録するために使用します

于 2012-12-17T09:42:56.977 に答える