2019年6月1日 星期六

Protocol Buffers - for C++


Protocol buffers基本上我把他想成是一個資料庫應用的延伸, 這話該如何說呢? 基本上他就是透過名為proto的meta file, 用以描述資料形態與內容(做encode/decode).

How does the Protocol Buffers work?

先定義你的message結構, 如
message Person {
  required string name = 1;
  required int32 id = 2;
  optional string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    required string number = 1;
    optional PhoneType type = 2 [default = HOME];
  }

  repeated PhoneNumber phone = 4;
}

再用protoc將該檔案轉成code, 目前支援(C++, Java and Python), 如下例子, 將brook.proto轉成C++(brook.pb.cc與brook.pb.h).
brook@vista:~/protobuf/CPP$ protoc --cpp_out=. brook.proto
brook@vista:~/protobuf/CPP$ ls
brook.pb.cc  brook.pb.h  brook.proto

這些code會包含存取每一個欄位的API(如下由doxygen產生的圖), 如email()與set_email(), 用以serialize/parse資料,

接著我們就可以用這些API寫一段code, 做serialize/parse資料
#include <iostream>
#include <fstream>
#include "brook.pb.h"
using namespace std;

static void _Serialize(void)
{
        Person person;
        person.set_name("John Doe");
        person.set_id(1234);
        person.set_email("jdoe@example.com");
        fstream output("myfile", ios::out | ios::binary);
        person.SerializeToOstream(&output);
}

static void _Parse(void)
{
        Person person;
        fstream input("myfile", ios::in | ios::binary);
        person.ParseFromIstream(&input);
        cout << "Name: " << person.name() << endl;
        cout << "E-mail: " << person.email() << endl;
}

int main(int argc, char *argv[])
{
        _Serialize();
        _Parse();
        return 0;
}

brook@vista:~/protobuf/CPP$ g++ main.c brook.pb.cc -lprotobuf
brook@vista:~/protobuf/CPP$ ./a.out
Name: John Doe
E-mail: jdoe@example.com


    參考資料:
  • protocol buffer簡介, https://developers.google.com/protocol-buffers/docs/overview





沒有留言:

張貼留言

熱門文章