Protocol Buffersを試す

C++でProtocol Buffersを使ってみる。

「整数のx,y座標を持つPoint型」を定義する。

// point.proto
package Test;

message Point
{
	optional int32 x = 1;
	optional int32 y = 2;
}

これを元にC++用のファイルを作ってもらう。

% protoc --cpp_out=. point.proto

これで2つのファイル point.pb.cc,point.pb.h が作られる。

package宣言とmessage型宣言により、上記の型は C++ではTest::Pointという型になる。

次にPoint型をシリアライズしてファイルに保存するプログラム、そしてそれを読み込んでPoint型に復元するプログラムを書く。

まずシリアライズ→保存。

// pwrite
#include <iostream>
#include <fstream>
#include <cstdio>
#include "point.pb.h"

using namespace std;

int main(int argc, char* argv[])
{
  Test::Point pt;

  pt.set_x(100);
  pt.set_y(-20);

  fstream output(argv[1], ios::out | ios::trunc | ios::binary);
  if (!pt.SerializeToOstream(&output)) {
    return -1;
  }
  return 0;
}


次にファイル読み込み→データ復元

// pread
#include <iostream>
#include <fstream>
#include <cstdio>
#include "point.pb.h"

using namespace std;

int main(int argc, char* argv[])
{
  Test::Point pt;

  fstream input(argv[1], ios::in | ios::binary);
  if (!pt.ParseFromIstream(&input)) {
    return -1;
  }

  fprintf(stderr, "%d %d\n",
	  pt.x(),
	  pt.y() );

  return 0;
}

コンパイルして実行してみる

% ./pwrite hoge
% hexdump hoge 
0000000 08 64 10 ec ff ff ff ff ff ff ff ff 01         
000000d
% ./pread hoge
100 -20
%

なるほどこれは簡単。C++ではデータのシリアライズ方法で頭を悩ますことが多かったけど、これからはProtocol Buffersを使えば良さそう。