protobuf在我看来就是把在protobuf里面写一个结构体,定义其属性。然后经过proto编译会生成对应的方法,我们可以调用这些方法对该结构体进行一个序列化和反序列化。
样例1编写proto文件
背景
写一个通讯录demo来理解prtobuf的序列化。
编写proto文件
在protobuf里一个对象称为一个消息体,用message表示。
在编写proto文件时有几个注意事项:
1.程序开头要指定语法版本
2.需要声明代码的命名空间
3.为了防止冲突,每个属性都要有唯一编号
code1
//指定语法版本
syntax="proto3";
//声明代码的命名空间
package contacts;
message contact
{
//为了防止冲突,每个属性都要有唯一编号
uint64 sn=1;
string name=2;
float score=3;
};
编译
通过protoc命令去编译 ,后面指定 语言类型,=后面指定编译后生成的文件的路径 以及 指定要编译的proto文件:
protoc --cpp_out=. contacts.proto
生成
编译后会生成两个文件,一个contacts.cc文件,一个contacts.h文件。
在contacts.h文件下我们可以看见contact类继承于Message这个消息体:
我们跳转到Message这个类,发现它继承MessageLite这个类:
跳转到MessageLite这个类,我们发现它下面有很多接口的声明,其中有两个接口:
SerializePartialToArray()这个接口是把消息体序列化到一个容器中。
SerializeToArray()这个接口是把消息体序列化为一个字符串。
样例2 实现序列化与反序列化
code
#include<iostream>
#include"contacts.pb.h"
int main()
{
contacts::contact conn; //创建一个 contacts命名空间下的contact类 类型的对象 conn
//序列化
conn.set_sn(1001);
conn.set_name("小明");
conn.set_score(250);
//将持久化的对象存储在 str对象中 可以进行持久化存储 或 网络化传输
std::string str=conn.SerializeAsString();
//反序列化
contacts::contact stu;
bool res=stu.ParseFromString(str);
if(res==false)
{
std::cout<<"反序列化失败!"<<std::endl;
return -1;
}
//属性经过封装 我们通过访问 方法去访问属性
std:: cout<<stu.sn()<< std::endl;
std:: cout<<stu.name()<<std::endl;
std:: cout<<stu.score()<<std::endl;
return 0;
}
编译
一定要链接protobuf这个库,不然编译时会报链接错误