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 1Person* 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 2person = 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