1

私が探しているのは、RakNetに組み込まれているシリアル化ライブラリ(現在のプロジェクトでは使用できません)に似ています。バイナリストリームをローカルでカスタム形式に保存/ロードし、ネットワーク経由で送信できるようにする必要があります。ネットワークの部分は解決されましたが、特に圧縮メソッドがないと非効率になるため、さまざまなタイプのデータをすべてバイナリにシリアル化するための独自のメソッドを作成したくありません。

これは、RakNetのビットストリームがどのように機能するかに似たいくつかの擬似コードです。これは私が探しているものに沿ったものです。

class Foo
{
public:
    void Foo::save(BitStream& out)
    {
        out->write(m_someInt);
        out->write(m_someBool);
        m_someBar.save(out);

        // Alternative syntax
        out->write<int>(m_someInt);

        // Also, you can define custom serialization for custom types so you can do this...
        out->write<Bar>(m_someBar);

        // Or this...
        out->write(m_someBar);     
    }

    void Foo::load(BitStream& in)
    {
        in->read(m_someInt);
        in->read(m_someBool);
        in->read(m_someBar);
    }

private:
    int m_someInt;
    bool m_someBool;
    Bar m_someBar;
};

このようなことを可能にする無料のC++ライブラリはありますか?基本的には、データをバイナリにパックし、シリアル化のために圧縮してから、データにフィードバックできるようにバイナリに解凍するものが必要です。

編集、詳細情報の追加:
残念ながら、GoogleProtocolBuffersもBoostSerializationも私のニーズには対応しません。どちらもオブジェクトメンバーをシリアル化することを期待しています。データをシリアル化する必要があります。たとえば、私がを持っていてstd::vector<Person>、クラスPersonstd::stringfor nameと他のデータが含まれているとしましょう。しかし、それらの名前をシリアル化および逆シリアル化するだけです。Google Protocol Buffersを使用すると、シリアル化のために全体としてPersonオブジェクトを提供することが期待されます。ただし、Boost Serializationを使用してこれを達成することはできますが、別のシナリオで全体が必要な場合はPersonシリアル化するには、それを行う方法はありません。すべてをシリアル化するか、まったくシリアル化する必要がありません。基本的に、バイナリストリームを作成するにはかなりの柔軟性が必要ですが、適切と思われます。ストリームとの間のバイナリデータの読み取りと書き込み、およびストリームの圧縮/解凍を管理するのに役立つライブラリが必要です。

4

1 に答える 1

2
  1. Googleプロトコルバッファ
  2. シリアル化を後押し

アップデート

更新された質問を見ると、必要なことを正確に実行する小さなカスタムライブラリを作成するのが最も簡単かもしれないと思います。私は似たようなものを持っていて、それはほんの数百行のコードです(圧縮なし)。この種のコードの単体テストを作成するのは非常に簡単なので、最初から信頼できます。

カスタムタイプをシリアル化するために、saveメソッドとloadメソッドを持つPersistent基本クラスがあります。

class Storage {
public:
  void writeInt( int i );
  void writeString( string s );
  int readInt();
  string readString();
};

class Persistent {
public:
  virtual void save( Storage & storage ) = 0;
  virtual void load( Storage & storage ) = 0;
};

class Person : public Persistent {
private:
  int height;
  string name;
public:
  void save( Storage & storage ) {
    storage.writeInt( height );
    storage.writeString( name );
  }

  void load( Storage & storage ) {
    storage.readInt( height );
    storage.readString( name );
  }
};

そして、その上に、保存時にいくつかのタイプ情報を格納し、ロード時にFactoryを使用して新しいオブジェクトを作成する単純なレイヤーがあります。

これは、C ++のストリーム(私はあまり好きではないので、Storageクラス)を使用することでさらに単純化できます。または、&演算子を使用してロードをマージし、単一のメソッドに保存するというBoostのアプローチをコピーします。

于 2012-12-27T23:45:53.153 に答える