MessagePack for C++ 新機能追加 - 0.5.0リリース

MessagePack for C++のバージョン0.5.0をリリースしました。

  • 静的型のオブジェクトから msgpack::object を作成できるようになりました
  • MSGPACK_DEFINEマクロが定義されたクラスは、msgpack::object に変換できます
  • デシリアライザに新しいAPIを追加しました
  • "msgpackc"をリンクする必要が無くなりました。"msgpack"だけで済みます
  • MessagePack@SourceForge.net

古いバージョンとのバイナリ互換性はありません。注意してください。

msgpack::object

MessagePack for C++ では、デシリアライズされたオブジェクトは msgpack::object 型になります。
このオブジェクトは、動的型付けのオブジェクトに似た性質を持っており、様々な型のデータを包含できます。ネットワークからオブジェクトを受信する場合など、メッセージの型が事前に分からない場合に非常に良くマッチします。
通常は、この型を std::vector や std::string などの静的な型に変換を試みてから利用します。MessagePack for C++ では、msgpack::object を様々な静的な型に変換する機能を提供しています。ユーザー定義のクラスに変換することも可能です。


ここで、MessagePackを使ってプログラムを書いていると、msgpack::object 型のままでオブジェクトを扱いたいケースが出てきます。すると今度は逆に、std::vector などの静的な型から msgpack::object を作りたくなってきます。
そこで今回のリリースでは、ユーザー定義クラスを含む任意の型から、msgpack::object を作成できるようにする仕組みを追加しました。


まず、std::vector や std::map などのクラスには、標準で対応しています。
ユーザー定義のクラスをmsgpack::objectに変換できるようにするには、MSGPACK_DEFINEマクロを使います:

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

// ユーザー定義クラス
class myclass {
public:
    std::string str;       // メンバ変数
    std::vector<int> vec;  // メンバ変数

    MSGPACK_DEFINE(str, vec);  // メンバ変数を列挙
};

int main(void)
{
    // 静的型から...
    myclass d;
    d.str = "msgpack";
    d.vec.push_back(1);
    d.vec.push_back(2);

    // msgpack::objectに変換
    msgpack::zone zone;   // zoneを作る
    msgpack::object obj(d, &zone);  // メモリはzoneから確保

    std::cout << obj << std::endl;  //=> ["msgpack", [1, 2]]
}


整数や浮動小数点数などのプリミティブ型は、単純に値を渡すだけで作成できます:

int main(void)
{
    msgpack::object obj1(1);     // 整数
    msgpack::object obj2(0.1);   // 浮動小数点数
    msgpack::object obj3(true);  // 真偽値
}


ちなみに、値を渡さないと nil になります:

int main(void)
{
    msgpack::object obj;
    if(obj.is_nil()) {
        std::cout << obj << std::endl;  //=> nil
    }
}

新しいデシリアライザAPI

デシリアライザのAPIが使いやすくなりました。
以前は引数の数が多かったり、reset() や release_zone() などの分かりにくい関数を呼び出す必要がありましたが、それが不要になりました:

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

int main(void)
{
    // 2要素の配列を用意
    std::vector<int> vec;
    vec.push_back(1);
    vec.push_back(2);

    // シリアライズ
    msgpack::sbuffer sbuf;
    msgpack::pack(sbuf, vec);

    // デシリアライズ
    msgpack::unpacked result;
    msgpack::unpack(&result, sbuf.data(), sbuf.size());

    // 結果を表示してみる
    std::cout << result.get() << std::endl;  //=> [1, 2]

    // 結果の中身:
    std::auto_ptr<msgpack::zone> z = result.zone();
    msgpack::object obj = result.get();
}

もっと詳しく

テストケースは、すべての機能の使い方を一通り網羅しています:

IRCチャットやRPCなどの情報は、ウェブサイトから辿ってみてください。