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を使えば良さそう。