Protobuf 调试踩坑记录

这是一次记录在使用protobuf中踩坑的记录,做一次记录整理,也希望能给其他遇到坑的同学一些帮助。

目录

背景:

踩坑记录

problem 1:

solution:

problem 2:

solution:

problem 3:

 solution:

转存失败重新上传取消​编辑problem 4:

 solution:

总结


背景:

本次开发环境是一个跨平台的通信模板,其中一端平台不支持proto生成的c++的文件,只能使用nanopb生成c的文件,而另一端用的c++的,跨平台通信涉及数据内存拷贝,编码解码工作

ps:关于protobuf和nanopb使用和介绍一大堆教程文档就不做赘述了

踩坑记录

problem 1:

结构体赋值传输过去后直接进行数据拷贝,结果报错了,定位问题:

写proto时候会写一个message,如果是一个结构体

nanopb生成的.h头文件中也会生成一个结构体,使用nanopb时候可以直接定义一个结构体变量,然后进行赋值,

使用c++会生成一个hpp文件,它会定义一个结构体同名的类

在调试中添加打印查看结构体数据长度:

使用nanopb端打印

 c++打印:

 结果:

 (此处坑看着很简单,常识性错误,提醒使用第三方工具一定要看它生成文件)

solution:

它们的内存和长度完全不同,不可以将结构体数据直接进行拷贝,类似“memcpy"是一定错误的,必须将结构进行编码传输过去后再进行解码工作才可以。

problem 2:

在上面问题解决添加nanopb编码工作,结果编码时候后也没提示报错程序运行直接崩溃

调试过程耽搁很久,但最后问题也很简单

在proto定义中

repeated:在格式正确的消息中,此字段类型可以重复零次或多次。系统会保留重复值的。

这个消息类型生成的类成员在c++中类似容器,可以动态分配内存大小

然而在nanopb中,repeated关键字必须指定最大长度,让c语言一次分配好内存大小

solution:

在proto定义路径下:再写一个与proto同名的.options文件

如下:

 这样再使用nanopb生成消息文件,在生成头文件中多了消息的最大长度

 这时候就正常编码了

problem 3:

3.第二步添加编码后,依然无法正确发送数据,添加打印定位到编码失败报错-array max size exceeded

 

 solution:

修改结构体长度,之前定义的结构体长度算都有10k了,并将data_tmp大小改为生成的头文件中定义的结构大小

problem 4:

在nanopb编码后并且程序成功运行,但是当c++解码后probobuf内容都是零;

 上面截图可以看到我先把结构体数据打印出来,再进行编码,编码后直接解码打印查看:

结构体有值,编码后再解码发现此时就已经为零。

最终调试半天发现,在nanopb中,

所有repeated消息在生成的结构体会有个成员pb_size_t count这个值必须指定为实际使用的值,

类似one of 的消息,也必须指定使用哪一个,这样才能成功编码

当给这些变量赋值后:再看打印,成功解析

 solution:

编码后一定注意生成的结构体内容,像动态消息  有pb_size_t的变量一定按实际填充数量给它赋值

总结

上面这些看着都是一些小问题,但在实际开发调试中耽搁好几天时间,重复的代码修改很枯燥,非常耗费精力和时间, 所以整理下来,在开发中,要细心有耐心,保持质疑,不要相信玄学,尤其对第三方库,一定多去看使用文档,多查多问,保持记录的习惯。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/53082.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

怎么加密文件夹才更安全?安全文件夹加密软件推荐

文件夹加密可以让其中数据更加安全,但并非所有加密方式都能够提高极高的安全强度。那么,怎么加密文件夹才更安全呢?下面我们就来了解一下那些安全的文件夹加密软件。 文件夹加密超级大师 如果要评选最安全的文件夹加密软件,那么文…

掌握Python的X篇_19_函数的定义与调用

文章目录 1. 函数2. 函数的定义3. 函数调用 1. 函数 在Python,函数是一种基本的编程接口,因为函数的调用只关心参数输入和返回值,所以使得我们可以更好地进行编程分工。 以下程序的功能是得到输入的三个数字的平方值,根据前面所学…

ChatGPT即将取代程序员

W...Y的主页 相信ChatGPT大家已经都不陌生,我们经常会在工作和学习中应用。但是ChatGPT的发展速度飞快。功能也越来越全面。ChatGPT的文章也是层次不穷的出现,ChatGPT即将取代程序员的消息也铺天盖地。那ChatGPT真的会取代程序员吗?我们是否…

ES6系列之let、const、箭头函数使用的坑

变量提升块级作用域的重要性箭头函数this的指向rest参数和arguments 1.ECMAScript与Js的关系 2.Babel转码器 Babel是一个广泛使用的ES6转码器,可以将ES6代码转为ES5代码,从而在老版本的浏览器执行。这意味着,你可以用ES6的方式编写程序&…

Linux【网络基础】数据链路层IP协议技术补充DNSDHCP

文章目录 一、数据链路层(1)数据链路层与网络层的关联(2)局域网通信原理(3)以太网协议(4)ARP协议 二、NAT协议三、NAPT协议四、ICMP协议五、DNS六、DHCP 一、数据链路层 &#xff0…

ORB-SLAM2学习笔记6之D435i双目IR相机运行ROS版ORB-SLAM2并发布位姿pose的rostopic

文章目录 0 引言1 D435i相机配置2 新增发布双目位姿功能2.1 新增d435i_stereo.cc代码2.2 修改CMakeLists.txt2.3 新增配置文件D435i.yaml 3 编译运行和结果3.1 编译运行3.2 结果3.3 可能出现的问题 0 引言 ORB-SLAM2学习笔记1已成功编译安装ROS版本ORB-SLAM2到本地&#xff0c…

LAXCUS分布式操作系统引领科技潮流,进入百度首页

信息源自某家网络平台,以下原样摘抄贴出。 随着科技的飞速发展,分布式操作系统做为通用基础平台,为大数据、高性能计算、人工智能提供了强大的数据和算力支持,已经成为了当今计算机领域的研究热点。近日,一款名为LAXCU…

Mybatis引出的一系列问题-JDBC 的探究

1 引入对JDBC的理解-1 一般来说,Java应用程序访问数据库的过程是: 装载数据库驱动程序;通过jdbc建立数据库连接;访问数据库,执行sql语句;断开数据库连接。 Public void FindAllUsers(){//1、装载sqlserve…

开放式耳机的音质不如入耳式耳机吗?开放式耳机的优缺点?

​开放式耳机的音质不一定不如入耳式耳机。音质取决于多种因素,包括耳机的设计、音频技术和材料质量等。因此,不能简单地将开放式耳机和入耳式耳机进行比较,并得出开放式耳机的音质不如入耳式的结论。不同的耳机类型都有各自的优势和劣势&…

vue+element中如何设置单个el-date-picker开始时间和结束时间关联

功能&#xff1a;选了开始时间&#xff0c;则结束时间只能选择开始时间之后的&#xff1b;选了结束时间&#xff0c;则开始时间只能选择结束时间之前的 重点是picker-options属性 图示&#xff1a; 代码展示: // body 内部<el-form-item><el-date-pickerv-model&qu…

面试题总结

文章目录 第一阶段:网络1、osi七层模型、tcp\ip 五层模型2、三次握手四次挥手3、交换机路由器工作原理4、vlan的作用5、icmp协议Linux1、cpu、内存、io、磁盘容量、网络流量、load average2、lvm逻辑卷如何创建3、raid磁盘阵列4、开机引导过程5、软连接硬链接6、查找文件命令7…

在windows下安装ruby使用gem

在windows下安装ruby使用gem 1.下载安装ruby环境2.使用gem3.gem换源 1.下载安装ruby环境 ruby下载地址 选择合适的版本进行下载和安装&#xff1a; 在安装的时候&#xff0c;请勾选Add Ruby executables to your PATH这个选项&#xff0c;添加环境变量&#xff1a; 安装Ruby成…