这是一次记录在使用protobuf中踩坑的记录,做一次记录整理,也希望能给其他遇到坑的同学一些帮助。
目录
背景:
踩坑记录
problem 1:
solution:
problem 2:
solution:
problem 3:
solution:
转存失败重新上传取消编辑problem 4:
solution:
总结
本次开发环境是一个跨平台的通信模板,其中一端平台不支持proto生成的c++的文件,只能使用nanopb生成c的文件,而另一端用的c++的,跨平台通信涉及数据内存拷贝,编码解码工作
ps:关于protobuf和nanopb使用和介绍一大堆教程文档就不做赘述了
结构体赋值传输过去后直接进行数据拷贝,结果报错了,定位问题:
写proto时候会写一个message,如果是一个结构体
nanopb生成的.h头文件中也会生成一个结构体,使用nanopb时候可以直接定义一个结构体变量,然后进行赋值,
使用c++会生成一个hpp文件,它会定义一个结构体同名的类
在调试中添加打印查看结构体数据长度:
使用nanopb端打印
c++打印:
结果:
(此处坑看着很简单,常识性错误,提醒使用第三方工具一定要看它生成文件)
它们的内存和长度完全不同,不可以将结构体数据直接进行拷贝,类似“memcpy"是一定错误的,必须将结构进行编码传输过去后再进行解码工作才可以。
在上面问题解决添加nanopb编码工作,结果编码时候后也没提示报错程序运行直接崩溃
调试过程耽搁很久,但最后问题也很简单
在proto定义中
repeated
:在格式正确的消息中,此字段类型可以重复零次或多次。系统会保留重复值的。
这个消息类型生成的类成员在c++中类似容器,可以动态分配内存大小
然而在nanopb中,repeated关键字必须指定最大长度,让c语言一次分配好内存大小
在proto定义路径下:再写一个与proto同名的.options文件
如下:
这样再使用nanopb生成消息文件,在生成头文件中多了消息的最大长度
这时候就正常编码了
3.第二步添加编码后,依然无法正确发送数据,添加打印定位到编码失败报错-array max size exceeded
修改结构体长度,之前定义的结构体长度算都有10k了,并将data_tmp大小改为生成的头文件中定义的结构大小
在nanopb编码后并且程序成功运行,但是当c++解码后probobuf内容都是零;
上面截图可以看到我先把结构体数据打印出来,再进行编码,编码后直接解码打印查看:
结构体有值,编码后再解码发现此时就已经为零。
最终调试半天发现,在nanopb中,
所有repeated消息在生成的结构体会有个成员pb_size_t count这个值必须指定为实际使用的值,
类似one of 的消息,也必须指定使用哪一个,这样才能成功编码
编码后一定注意生成的结构体内容,像动态消息 有pb_size_t的变量一定按实际填充数量给它赋值
上面这些看着都是一些小问题,但在实际开发调试中耽搁好几天时间,重复的代码修改很枯燥,非常耗费精力和时间, 所以整理下来,在开发中,要细心有耐心,保持质疑,不要相信玄学,尤其对第三方库,一定多去看使用文档,多查多问,保持记录的习惯。