一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情。
前面的章节讲述了如何将protobuf环境配置到VS+Qt的环境,那么这一章节就来讲述下,如何使用并解析复杂的嵌套式protobuf结构。
今天我们就以组装以及解析两大部分分别说明吧!
今天使用的例子如下:
syntax = "proto3";
package JCProto;
message Test_st1
{
string s1 = 1;
string s2 = 2;
repeated Child_Test1 test1 = 3;
}
message Child_Test1
{
string s1 = 1;
int32 n1 = 2;
}
当前代码只是例子,名字都是随意定义的,大家在实际项目中千万不要写成这个样子呀!你就准备接收项目经理的批评吧,哈哈!
上述protobuf说明:
首先第一句话:syntax = "proto3"; 代表是使用了protobuf3结构,这个是一定要需要写清楚的,如果不写的话,你的电脑里存在protobuf2和3两个版本的时候,最容易混淆了,大家应该懂得版本冲突的问题吧!
该protobuf中存在了两个结构:Test_st1、Child_Test1。很明显,Child_Test1是属于Test_st1的子结构,并且是一种类似于vector容器的结构体。
如果不是很清楚的,可以理解成C++版的结构体
vector类似于repeated。也相当于数组
一开始很多人不是很理解这个关键词的意思,这么一转换就很清楚看出是什么意思了。
那么,我们来实际的功能操作吧!
功能1:组装protobuf结构体
难点:如何存储数组类的结构体?
普通的string以及int赋值很好处理,直接使用goole内部的函数就可以了,重点就讲解下如何给结构体如何赋值。
1:声明protobuf定义的结构体,Test_st1
JCProto::Test_st1 cmdTest;
JCProto这是什么呢? 类似于咱们在C++中命名空间作用,这样说大家就会很好理解了。
简单的字符串或者是整型赋值写法,如下:
std::string sContent = "需要赋值的数据";
cmdTest.set_s1(sContent);
结构体赋值写法,如下:
定义Child_Test1 结构,并设置每一条数据的赋值,类似于vector的赋值,最主要的区别在于protobuf这里不是pust_back而已。
JCProto::Child_Test1 cmdChild;
cmdChild.set_s1(); //参数是需要赋值的实际内容
cmdChild.set_n1(); //参数是需要赋值的实际内容
每一条的结构写好了,接下来,该如何赋值到repeated中呢?这也是重点哟~
第一步:需要new一个Child_Test结构数据,相当于C++中类的new的方式
JCProto::Child_Test1 *cmdChild = new JCProto::Child_Test1;
cmdChild->set_s1(); //参数是需要赋值的实际内容
cmdChild->set_n1(); //参数是需要赋值的实际内容
cmdTest->set_allocated_test1(cmdChild);
重点就是最后一句话,使用了set_allocated的方法,直接存储到cmdSt中,这里要看清楚了,不是cmdChild,而是cmdSt中!!
最后的最后,一定要记得释放你创建的资源
cmdTest.release_test1();
有些友友们,直接只用了之后早就忘记了释放资源了,这是不对的,如果你觉得手动释放麻烦,可以使用另一种方式,让goole帮你释放,例如:mutable_pos方法
但是,我不建议使用mutable_pos方法,啥也没有手动释放的安全(这是不是一个C++程序员的通病呢?)
到这里,protobuf数据就已经组装完成了,最后直接转换成json格式的字符串就可以啦!
std::string sJsonData = "";
JCJson2Pb::PbMsg2JsonStr(cmdTest, sJsonData);
主要是 PbMsg2JsonStr 方法,查阅资料大家都可以找到protobuf与json的转换函数,这里也就不再说明啦!
功能2:解析protobuf数据
功能1将protobuf转换成了json数据,那么这里,就是将json数据转换成protobuf结构了。
JCProto::Test_st1 cmdTest;
//将json数据转成protobuf结构
if (JCJson2Pb::JsonStr2PbMsg(sReceivedData, cmdTest) == false)
{
//数据解析错误,直接返回
return false;
}
JsonStr2PbMsg 这里重点的的转换函数,也是在protobuf与json转换中的。
此时,cmdTest中已经存储好了转换后的json结构了,那么最主要的解析还是嵌套的结构体中,repeated
因为是类似于vector的容器方式,那么,在拿数据的时候也需要使用遍历的方式。获取repeated的大小
for(int i = 0; i < cmdTest.test1_size(); i++)
{
//在这里,处理每一条数据
JCProto::Child_Test1 cmdChild = cmdTest.test1(i);
//解析数据
std::string s1 = cmdChild.s1();
int n1 = cmdChild.n1();
}
是不是很类似于vector拿数据呢?
到这里,解析、组装 嵌套的protobuf结构已经讲解完成了,如果有不明白的可以留言哟!
我是中国好公民st,一名C++开发程序猿~