ProtoBuffer使用笔记

ProtoBuffer是由谷歌研发的对象序列化和反序列化的开源工具,ProtoBuffer和Xml类似,都是数据描述工具,后者使用更为广泛,前者Google内部使用且具有更高的效率。该工具安装和使用都很简单,查看了下网上贴代码的居多,这里整理下以便以后使用。

1.安装

sudo apt-get install protobuf-compiler

 

2.说明文档

语法说明请参考:

[1]. Protocol Buffer技术详解(语言规范)

 简单例子请参考:

[1]. Google Protocol Buffers浅析(一,二,三,四)(windows下的使用,linux用户可参考其语法)

[2]. ProtoBuf 常用序列化/反序列化API

 

3. Eclipse CDT下使用ProtoBuffer

编写一个用户信息列表的描述,并完成对象序列化和反序列化操作。

a. 新建项目

建立一个新的c++ project,命名为TestPbuffer,并建立文件夹src, data, proto:

b. 数据描述

在目录proto下添加代码,person.proto,并编辑加入以下代码:

message Person{
    required string name = 1;
    required int32  age  = 2;
    optional string email = 3;
    enum PhoneType{
        HOME = 1;
        MOBILE = 2;
        WORK = 3;
    }
    message Phone{
        required int64 id = 1;
        optional PhoneType type = 2 [default = HOME];
    }
    repeated Phone phoneNum = 4;
}

message UserList{
    required string name = 1;
    repeated Person users = 2;
}

Proto文件与xml类似,能够对数据进行格式化的描述,以上的数据描述完成了用户信息记录列表的定义。具体含义请参阅:Protocol Buffer技术详解(语言规范)

c. 生成c++代码

在控制台下跳转到目录proto,然后执行以下编译命令:

$ protoc person.proto --cpp_out=../src/

生成的c++文件person.pb.h和person.pb.cc存放在src下。对象的序列化和反序列化就是通过这两个文件完成操作了。

d. 配置Include和Link

右击project的Propertise->C++ Build->Setting,具体配置如下图所示:

e.编写测试程序

在src目录下添加TestProtoBuffer.cpp文件,并添加以下代码:

//============================================================================
// Name        : TestPbuffer.cpp
// Author      : xiankai.chen
// Version     :
// Copyright   : xiankai.chen@qq.com
// Description : Test proto buffer in C++, Ansi-style
//============================================================================

#include <iostream>
#include <fstream>
#include <string>

#include "person.pb.h"

using namespace std;

int main() {
    /*write object to file*/
    UserList user_list;

    user_list.set_name("用户列表");
    //add person 1
    Person* person;
    Person::Phone *phone;
    person = user_list.add_users();
    person->set_name("cxk");
    person->set_age(30);
    person->set_email("xiankai.chen@qq.com");
    phone = person->add_phonenum();
    phone->set_type(Person::HOME);
    phone->set_id(13418638333);
    phone = person->add_phonenum();
    phone->set_type(Person::MOBILE);
    phone->set_id(13234444555);

    //add person 2
    person = user_list.add_users();
    person->set_name("lgm");
    person->set_age(30);
    person->set_email("77015684@gmail.com");
    phone = person->add_phonenum();
    phone->set_type(Person::HOME);
    phone->set_id(13344655445);
    phone = person->add_phonenum();
    phone->set_type(Person::MOBILE);
    phone->set_id(13765546785);

    fstream output("./data/myinfo.dat",ios::out|ios::binary);
    user_list.SerializeToOstream(&output);
    output.close();
    output.clear();


    /*read object from file*/
    fstream input("./data/myinfo.dat",ios::in|ios::binary);
    UserList userlist_in;
    if(!userlist_in.ParseFromIstream(&input))
    {
        cout<<"parse error"<<endl;
        return -1;
    }
    cout<<"userlist name: "<< userlist_in.name() <<endl;

    for(int i = 0; i < userlist_in.users_size(); i++)
    {
        cout<<"person["<<i<<"] name:"<< userlist_in.users(i).name()<< endl;
        cout<<"person["<<i<<"]  age:"<< userlist_in.users(i).age()<< endl;
        cout<<"person["<<i<<"]email:"<< userlist_in.users(i).email()<< endl;
        for(int j = 0; j < userlist_in.users(i).phonenum_size(); j++)
        {
            cout<<"person["<<i<<"] phonenum["<<j<<"] type:"<< userlist_in.users(i).phonenum(j).type()<< endl;
            cout<<"person["<<i<<"] phonenum["<<j<<"] no:"<< userlist_in.users(i).phonenum(j).id()<< endl;
        }
    }
    input.close();
    input.clear();

    return 0;
}

 

f.执行测试结果

如下所示

userlist name: 用户列表
person[0] name:cxk
person[0]  age:30
person[0]email:xiankai.chen@qq.com
person[0] phonenum[0] type:1
person[0] phonenum[0] no:13418638333
person[0] phonenum[1] type:2
person[0] phonenum[1] no:13234444555
person[1] name:lgm
person[1]  age:30
person[1]email:77015684@gmail.com
person[1] phonenum[0] type:1
person[1] phonenum[0] no:13344655445
person[1] phonenum[1] type:2
person[1] phonenum[1] no:13765546785

 

g. 工程代码

下载链接:TestPbuffer.tar.gz

 

posted @ 2017-01-18 14:17  horsetail  阅读(8018)  评论(0编辑  收藏  举报