前回作った、protobuf-cの書込みプログラムを見ていこう。
Githubのgistにも残しておこう。
結果の出力をファイルに変更している。
https://gist.github.com/hirokuma/11fed489bd97fa62daed686dec622646
ルールとして、xxx__INITを使った初期化は、インスタンスの定義と同時に行うしかない、というものがある。
こんなところや、こんなところである。
addrbook.peopleなんかは、malloc()してmemcpy()なんかでコピーさせたかったのだが、初期値用のインスタンスを作っておいて、それをmemcpy()(実装では代入)させている。
まあ、forの中で初期化させる意味は無いので、外に出した方がよかろう。
よく見ると、tutorial__address_book__init()という関数も用意されていた。
やってることは、同じだ。
01: void tutorial__address_book__init 02: (Tutorial__AddressBook *message) 03: { 04: static const Tutorial__AddressBook init_value = TUTORIAL__ADDRESS_BOOK__INIT; 05: *message = init_value; 06: }
static constになっているから、メモリが静的に割り当てられそうな気がするけど、ROM側になるからそこまで気にしなくてよいか。
マクロでの代入と関数での初期化をそれぞれやると、それぞれメモリを取りそうだから、複数使うのであれば関数呼び出しにした方が小さくできるかもしれない。
いっそのこと、static inlineにしてヘッダに置いた方が・・・などと思ったが、初期化にそこまで気合い入れなくてもいいんじゃなかろうかね。
それ以外は、取り立てて書くことがないなー、と思っていたのだが、ヘッダファイルを見ると使っていない構造体があった。
- ProtobufCAllocator
- ProtobufCBuffer
pack_to_buffer()とunpack/free_unpacked()の引数で使われている。
名前からすると、メモリ関係をやってくれそうだが、どうだろう?
https://github.com/protobuf-c/protobuf-c/wiki/The-protobuf-c-Library#virtual-buffers
ProtobufCBufferは、append()を持つようだ。
ここでは、FILE*への書込みを例にしている。
gistに置いたサンプルでは、get_packed_size()でサイズを取ってきて、malloc()してpack()、とやっているが、ファイルに吐き出していくのであれば、サイズは気にせず、malloc()もいらず、pack()の代わりにpack_to_buffer()でオープンしているFILE*に吐き出していけばよいだろう。
RAMに置きたい場合は、ProtobufCBufferSimpleが使えるかもしれん。
ただ、これは配列でメモリを確保したものを与えるらしい。
しかし、allocatorとしてmalloc/free()を使ってもいるようだ・・・。
なんだこりゃ?
protobuf_c_buffer_simple_append()を見た感じでは、初期バッファを超えない間は配列を使い、超したらmallocしていくのかな?
realloc()ではなくmalloc()しか使って無さそうだけど、リークしないんだろうか?
メモリを確保して、コピーしてからfreeしているような感じもするので、大丈夫なのか。
全部見ていく気力は無いので、動かしてみるのがよいかな。
0 件のコメント:
コメントを投稿
コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。
注: コメントを投稿できるのは、このブログのメンバーだけです。