2017-08-23 58 views
0

現在のプロジェクトでMsgpack(C++)をシリアライゼーションライブラリとして評価しています。それは私のニーズの大部分を満たしているようですが、私はそれについてオンラインで多くの情報を見つけませんでした。 Msgpackは、シリアル化するデータ構造の異なるバージョンを読み込むことをサポートしていますか?Msgpackにバージョン管理機能がありますか

例えば、私は次の構造をシリアライズ:

struct foo { 
    int a; 
    float b; 
}; 

以降の構造上記へと進化:

struct foo { 
    int a; 
    float b; 
    std::string c; 
}; 

はMsgpackを使用して新しいものに以前にシリアル化された構造を読み取ることが可能ですか? Boostライブラリは構造体と共にVERSIONのメタデータを追加することでそれを処理します。

+0

多分これはあなたの質問に答えます15579730/android-c-data-serialization Googleプロトコルバッファのような他の選択肢について考えることができます。 – user0042

答えて

2

はい、これを行うことができます。 foo_v1をパックして解凍した後、foo_v2a、およびbに変換すると、パックされた値が入ります。

#include <msgpack.hpp> 
#include <cassert> 
#include <iostream> 
#include <sstream> 

struct foo_v1 { 
    int a; 
    float b; 
    MSGPACK_DEFINE(a, b); // pack as ARRAY, order is important 
}; 

struct foo_v2 { 
    int a; 
    float b; 
    std::string c; 
    MSGPACK_DEFINE(a, b, c); // pack as ARRAY, order is important 
}; 

int main() { 
    foo_v1 v1 { 123, 45.67 }; 
    std::stringstream ss; 
    msgpack::pack(ss, v1); 

    auto oh = msgpack::unpack(ss.str().data(), ss.str().size()); 
    auto v2 = oh.get().as<foo_v2>(); 
    std::cout << "a: " << v2.a << std::endl; 
    std::cout << "b: " << v2.b << std::endl; 
    std::cout << "c: " << v2.c << std::endl; 
} 

実行デモ:https://wandbox.org/permlink/91wRtVdJJCC5IEDxあなたがfoo_v2をパックしてから、その後foo_v1abがパック値で満たされているとして、それを変換し、それを解凍した場合

同様に、cをスライスする(無視)。

#include <msgpack.hpp> 
#include <cassert> 
#include <iostream> 
#include <sstream> 

struct foo_v1 { 
    int a; 
    float b; 
    MSGPACK_DEFINE(a, b); // pack as ARRAY, order is important 
}; 

struct foo_v2 { 
    int a; 
    float b; 
    std::string c; 
    MSGPACK_DEFINE(a, b, c); // pack as ARRAY, order is important 
}; 

int main() { 
    foo_v2 v2 { 123, 45.67, "hello" }; 
    std::stringstream ss; 
    msgpack::pack(ss, v2); 

    auto oh = msgpack::unpack(ss.str().data(), ss.str().size()); 
    auto v1 = oh.get().as<foo_v1>(); 
    std::cout << "a: " << v1.a << std::endl; 
    std::cout << "b: " << v1.b << std::endl; 
} 

実行デモ:https://wandbox.org/permlink/mxmSkVHebZFiOM1q

これらの例は、MSGPACK_DEFINEマクロを使用しています。 https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_adaptor#defining-custom-adaptorsを参照してください。 デフォルトではARRAYとしてパッキング/変換します。だから順序が重要です。 MSGPACK_DEFINE_MAPを使用する場合、ユーザークラスはMAPとしてパッキング/変換されます。 MAPのキーは、デフォルトでは変数名です。​​を使用して変更することができます(https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_adaptor#since-210を参照)。 MAPの値は、メンバ変数の値です。 MAPは、ARRAYよりも柔軟ですが、非効率です。

あなたがMSGPACK_DEFINE_MAPを使用する場合は、順序を気にする必要はありません。

デモ実行
#include <msgpack.hpp> 
#include <cassert> 
#include <iostream> 
#include <sstream> 

struct foo_v1 { 
    int a; 
    float b; 
    MSGPACK_DEFINE_MAP(a, b); // pack as MAP 
}; 

struct foo_v2 { 
    int a; 
    std::string c; 
    float b; 
    MSGPACK_DEFINE_MAP(a, c, b); // pack as MAP, c is at the middle position 
}; 

int main() { 
    foo_v2 v2 { 123, "hello", 45.67, }; 
    std::stringstream ss; 
    msgpack::pack(ss, v2); 

    auto oh = msgpack::unpack(ss.str().data(), ss.str().size()); 
    auto v1 = oh.get().as<foo_v1>(); 
    std::cout << "a: " << v1.a << std::endl; 
    std::cout << "b: " << v1.b << std::endl; 
} 

:ここhttps://wandbox.org/permlink/ozihpwXMJRpOhzT4

がよりcomplecated例です:デモを実行 https://github.com/msgpack/msgpack-c/blob/master/example/cpp03/map_based_versionup.cpp

:https://stackoverflow.com/questions/:https://wandbox.org/permlink/IUp94Tc4MiT4kU07

+0

ありがとうございました!これは私の質問に答える。 – Pranav

関連する問題