protocol buffers c言語の使用


次のソースコードの例は、https://github.com/protobuf-c/protobuf-c/wiki/Examples
メッセージの定義
message AMessage {
  required int32 a=1; 
  optional int32 b=2;
}

protobuf-cのインストール
コードで使用するにはprotoファイルをcソースにコンパイルする必要があるので、公式のコンパイルツールが必要です.
sudo apt-get install protobuf-c-compiler

コンパイル
protoc-c --c_out=. amessage.proto 
//    amessage.pb-c.c  amessage.pb-c.h    

コードでの使用
シーケンス化:
//serialize_main.c
#include 
#include 
#include "amessage.pb-c.h"

int main (int argc, const char * argv[]) 
{
  AMessage msg = AMESSAGE__INIT; // AMessage
  void *buf;                     // Buffer to store serialized data
  unsigned len;                  // Length of serialized data

  if (argc != 2 && argc != 3)
  {   // Allow one or two integers
    fprintf(stderr,"usage: amessage a [b]
"
); return 1; } msg.a = atoi(argv[1]); if (argc == 3) { msg.has_b = 1; msg.b = atoi(argv[2]); } len = amessage__get_packed_size(&msg); buf = malloc(len); amessage__pack(&msg,buf); fprintf(stderr,"Writing %d serialized bytes
"
,len); // See the length of message fwrite(buf,len,1,stdout); // Write to stdout to allow direct command line piping free(buf); // Free the allocated serialized buffer return 0; }

逆シーケンス化:
//unserialize_main.c
#include 
#include 
#include "amessage.pb-c.h"
#define MAX_MSG_SIZE 1024

static size_t
read_buffer (unsigned max_length, uint8_t *out)
{
  size_t cur_len = 0;
  size_t nread;
  while ((nread=fread(out + cur_len, 1, max_length - cur_len, stdin)) != 0)
  {
    cur_len += nread;
    if (cur_len == max_length)
    {
      fprintf(stderr, "max message length exceeded
"
); exit(1); } } return cur_len; } int main (int argc, const char * argv[]) { AMessage *msg; // Read packed message from standard-input. uint8_t buf[MAX_MSG_SIZE]; size_t msg_len = read_buffer (MAX_MSG_SIZE, buf); // Unpack the message using protobuf-c. msg = amessage__unpack(NULL, msg_len, buf); if (msg == NULL) { fprintf(stderr, "error unpacking incoming message
"
); exit(1); } // display the message's fields. printf("Received: a=%d",msg->a); // required field if (msg->has_b) // handle optional field printf(" b=%d",msg->b); printf("
"
); // Free the unpacked message amessage__free_unpacked(msg, NULL); return 0; }

実行可能プログラムのコンパイル
gcc -o serialize_main serialize_main.c amessage.pb-c.c -lprotobuf-c
gcc -o unserialize_main unserialize_main.c amessage.pb-c.c -lprotobuf-c

うんてん
./serialize_main 10086 -123 | ./unserialize_main