proto buffer学习

来源:互联网 发布:网络嗅探器 sniffer 编辑:程序博客网 时间:2024/05/20 23:32

1.安装

   在网站 http://code.google.com/p/protobuf/downloads/list上可以下载Protobuf的源代码.然后解压编译安装便可以使用
   安装步骤如下所示:
   tar -xzf protobuf-2.3.0.tar.gz
   cd protobuf-2.3.0
   ./configure --prefix=~/coding/protobuf
   make
   make check
   make install

2.例子

     描述:程序由两部分组成,第一部分被称为Writer,第二部分叫做Reader.
Writer负责将一些结构化的数据写入一个磁盘文件,Reader负责从该磁盘文件中独舞结构化数据并打印到屏幕上.准备用于演示的结构化数据是HelloWorld.它包含两个基本数据:ID,为一个整数类型的数据 str:字符串
  • 书写.proto文件:在protobuf术语中,结构化数据被称为Message
     文件Im.helloworld.proto:
     package Im;
     message helloworld
     {
             required int32 id=1;
             required string str=2;
             optional int32 opt=3;
     }
    
  • 编译.proto文件:写全路径
      ~/coding/protobuf/bin/protoc -I=/home/users/daihuan/coding/src/ --    cpp_out=/home/users/daihuan/coding/dst/ /home/users/daihuan/coding/src/Im.helloworld.proto 

命令将生成两个文件,在dst目录:Im.helloworld.pb.h Im.helloworld.pb.cc
  • 编写Writer和Reader
       Writer将把一个结构化数据写入磁盘,以便其他人来读取.假如我们不使用Protobuf.其实也有许多的选择.一个可能的方法是将数据转换为字符串,然后将字符串写入磁盘.数字123可以编程字符串"123" .对写的人来说很简单,但是对Reader的人来讲要求很高,必须了解Writer的细节
          文件Write.c
#include <iostream>
#include <fstream>
#include <string>
#include "Im.helloworld.pb.h"

using namespace std;
int main(void)
{
        Im::helloworld msg1;
        msg1.set_id(101);
        msg1.set_str("hello");

        fstream output("./log",ios::out|ios::trunc|ios::binary);

        if(!msg1.SerializeToOstream(&output)){
                cerr << "Failed to write msg." << endl;
                return -1;
        }
        return 0;
}
msg1是一个helloworld类的对象,set_id()用来设置id的值.SerializeToOstream将对象序列化后写入一个fstream流
编译:
g++ -g -o Write Write.c Im.helloworld.pb.h Im.helloworld.pb.cc -I../protobuf/include -L../protobuf/lib/ -lprotobuf  -lpthread

文件Reader.c
#include <iostream>
#include <fstream>
#include <string>
#include "Im.helloworld.pb.h"

using namespace std;

void ListMsg(const Im::helloworld &msg){
cout<<"msg.id="<<msg.id()<<endl;
cout<<"msg.str="<<msg.str()<<endl;
}

int main(int argc,char* argv[]){
        Im::helloworld msg1;
        {
                fstream input("./log",ios::in | ios::binary);
                if(!msg1.ParseFromIstream(&input)){
                   cerr<<"Failed to parse address book."<<endl;
                   return -1;
                }
        }
        ListMsg(msg1);
}
同样,Reader声明类helloworld的对象msg1,然后利用ParseFromIstream从一个fstream流中读取信息并反序列化.此后,ListMsg中采用get方法读取消息的内部消息,并进行打印输出操作
g++ -g -o Reader Reader.c Im.helloworld.pb.h Im.helloworld.pb.cc -I../protobuf/include -L../protobuf/lib/ -lprotobuf  -lpthread

执行./Write 和./Reader  会提示找不到lib 需要设置export LD_LIBRARY_PATH=~/coding/protobuf/lib/ 即ok
./Write 生成Log文件
./Reader


3.proto文件类型格式分析

1)定义一个消息类型:
message SearchRequest{
  required string query=1;
  optional int32 page_number=2;
  optional int32 result_per_page=3;
}
A. 特定域的类型:两个整型变量page_number和result_per_page,一个string类型的变量query.也可以定义为其他类型如:枚举和               其它message类型
B. 指派一个标签:这个标签是唯一的,它的范围可以是1~229-1。其中19000~19999是不可以使用的,protocol buffer内部使用。其中1~15保留为经常使用的消息元素。
C. 指定字段规则:指定的消息字段的规则有以下几种:a. required 一个结构良好的message必须有一个这样的字段。b. optional 结构良好的message有零个或者一个这样的字段。c.repeated这个字段可以重复任意多次(包括零次)。说明:在repeated后面加上[packed=true]可以取得更高效的编码。如:repeated int32 samples=4 [package=true]
D. 可以在一个文件中添加多个message,在编译生成cpp代码后,将对应多个类。
E. proto注释的添加和cpp一样,用双斜杠即可
F.运行protocol buffer编译器按照置顶的选项生成特定语言的代码,在生成的代码中包含了对proto文件中声明的变量的设定、取得、序列化消息到输出流和从输入流中分解出你的消息的操作。

2)标量值类型

3)Optional字段的默认值
     设定方法如:optional int32 result_per_page=3 [default=10]。如果没有指定:string默认值为空串,bool为false,数字类型的为零,枚举类型的默认值为枚举定义列表中的第一个值.

4) Optional字段的默认值
message SearchRequest{
  required string query=1;
  optional int32 page_number=2;
  optional int32 result_per_page=3 [default=10];
  enum Corpus{
      UNIVERSAl=0;
      WEB=1;
      IMAGES=2;
      LOCAL=3;
      NEWS=4;
      PRODUCTS=5;
      VIDEO=6;
}
     optional Corpus corpus=4 [default=UNIVERSAl]
}
外部message可以通过MessageType.EmmType取得其中的值

reference
[1]:http://www.ibm.com/developerworks/cn/linux/l-cn-gpb/
[2]:http://blog.chinaunix.net/uid-8625039-id-4430741.html
[3]:http://blog.csdn.net/eaglewood2005/article/details/4367378
0 0
原创粉丝点击