Protocol Buffers のチュートリアル覚書き
前々回と前回でやっと準備が整ったので、Protocol Bufferesのチュートリアルを実行します。そのメモです。
チュートリアルの実行
Protocol Bufferesでは、.protoファイルに規定の形式でデータ構造を書いてprotocというコンパイラにかけると、getter/setterに該当するコードを自動生成してくれます。
.protoの文法は、JavaやC++に似ていますが、クラス継承のような概念はありません。
データメンバーは、ネストさせたり、繰り返しを許したりできます。
詳細ドキュメントは、次のページにあります。
- Language Guide - Protocol Buffers - Google Code http://code.google.com/intl/ja/apis/protocolbuffers/docs/proto.html
.protoファイルのコンパイル
今回は、addressbook.protoというファイルをコンパイルします。examplesに最初から入っていたファイルです。
protoc --cpp_out=./ ./addressbook.proto
すると、次の2つのファイルが作成されます。
- addressbook.pb.cc
- addressbook.pb.h
# これらのファイルは、examplesディレクトリをコンパイルした時点(http://d.hatena.ne.jp/torazuka/20111204/protobuf)で存在しましたが、protocの実行によって再度生成されます。
コンパイルしてできたこれらのファイルに、addressbookのデータ構造を扱うコードが書かれています。自分で編集する必要はありません。どういったコードが提供されるかは、APIリファレンスで確認できます。
- C++ Generated Code - Protocol Buffers - Google Code http://code.google.com/intl/ja/apis/protocolbuffers/docs/reference/cpp-generated.html
アドレス帳にPersonを追加する
というわけで、データをやり取りしてみます。やり取りといっても、このチュートリアルでは、対ファイルだけですが。
examplesのコンパイルによって作成された、add_person_cppを実行します。
引数にデータ書き込み先のファイルが必要なので、protoc_middlemanという空ファイルを指定します。
$ ./add_person_cpp protoc_middleman Enter person ID number: 101 Enter name: takeshi Enter email address (blank for none): takeshi@hoge.com Enter a phone number (or leave blank to finish): 12345678 Is this a mobile, home, or work phone? home Enter a phone number (or leave blank to finish):
対話的にデータを入力します。これらが、protoc_middlemanに保存されます。
アドレス帳のリストを表示する
今度は、中身を取り出してみます。
あらかじめ用意されているlist_people_cppを実行します。
$ ./list_people_cpp protoc_middleman Person ID: 101 Name: takeshi E-mail address: takeshi@hoge.com Home phone #: 12345678
アドレス帳に格納されたデータが、整形表示されました。
これらのデータ入出力が、Protocol Bufferesの形式で行われているということのようです。
保存されているファイルの中身を確認
さらに入力してみます。
$ ./add_person_cpp protoc_middleman Enter person ID number: 102 Enter name: haruyo Enter email address (blank for none): haruyo@moga.com Enter a phone number (or leave blank to finish): 987654321 Is this a mobile, home, or work phone? mobile Enter a phone number (or leave blank to finish): 111122223 Is this a mobile, home, or work phone? work phone # 誤った入力値を与える(○work、×work phone) Unknown phone type. Using default. # .protoファイルで定義したデフォルト値が入る Enter a phone number (or leave blank to finish): 555555555 Is this a mobile, home, or work phone? work Enter a phone number (or leave blank to finish):
出力してみます。
$ ./list_people_cpp protoc_middleman Person ID: 101 Name: takeshi E-mail address: takeshi@hoge.com Home phone #: 12345678 Person ID: 102 Name: haruyo E-mail address: haruyo@moga.com Mobile phone #: 987654321 Home phone #: 111122223 Work phone #: 555555555
protoc_middlemanの中身を確認すると、こんな感じになっています。
普通に開いても読めないので、バイナリを表示します。
$ od -tc protoc_middleman 0000000 \n + \n \a t a k e s h i 020 e 032 020 t 0000020 a k e s h i @ h o g e . c o m " 0000040 \f \n \b 1 2 3 4 5 6 7 8 020 001 \n F \n 0000060 006 h a r u y o 020 f 032 017 h a r u y 0000100 o @ m o g a . c o m " \r \n \t 9 8 0000120 7 6 5 4 3 2 1 020 \0 " \v \n \t 1 1 1 0000140 1 2 2 2 2 3 " \r \n \t 5 5 5 5 5 5 0000160 5 5 5 020 002 0000165
メモ
そもそも、この一連の作業の目的は、Protocol Bufferesを使うことではなく、Protocol Bufferesのコードを読むための取っ掛かりを探すことでした。そうだったんかって感じですが、そうだったんですよ奥さん…。しかし、このチュートリアルだけをやっても、自分にはよくわかりませんです。トホホ
ただ、IDLのエンコード部分から読むのがとっつきやすそうだとは思いました。最初は、他言語実装との差分であるこの箇所は、コードリーディングをする上でオマケ的扱いになると思っていたのですが、自動生成部分は実行結果を出力コードで確認できるので、処理の過程を追いやすいかもしれません。(気のせいかもしれません)
あと、使うかなと思ったechoサーバは、このチュートリアルでは使いどころがありませんでした。そういうサンプルは自分で書けってことですよね、きっと。