一个栗子——序列化工具protobuf

对象序列化是将结构体对象转换为可传输的格式,如在网络传输中。C语言中结构体天然支持序列化,但面临对齐和大小端问题。对于跨语言如C到Python,需要工具如protobuf和nanopb协助。protobuf能实现跨平台和跨语言的序列化和反序列化,即使Python没有结构体和指针。通过示例展示了如何使用protobuf和nanopb在C和Python之间进行序列化和反序列化操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      对象序列化是做什么的,作为了一个常用C语言写代码的嵌入式工程师,最开始确实有些难以理解。直到遇到一些项目,才体会到对象序列化和反序列化的用处。

       对于C语言来说,结构体就可以定义对象,这种对象的数据就在内存中,已经序列化,想要将其传输,只需要对象的地址和长度即可。而接收端,只要有这个结构体的定义,很容易就可以将传输的内容,反序列化,最终得到传输的结构体对象的内容。但是,仅仅对于两端都是c语言实现的程序,就存在两个问题:结构体的对齐和数据大小端问题。对于这两条规则,序列化和反序列化两端,结构体的对齐规则和大小端必须一致,否则,反序列化就会出问题。相同语言尚且如此,跨语言呢,c语言结构体对象序列化的数据,用python 来反序列化呢,python可没有结构体,没有指针,怎么反序列化?这里我们就要借助第三方工具了,比如protobuf,借助它我们就可以实现跨平台(8bit/16bit/32bit mcu, 32bit/64bit cpu, windows /linux),跨语言(c语言/c++/java/go/python等),实现对象的序列化和反序列化。比如在32bit的单片上,我们借助protobuf 用C语言将一个结构体对象序列化,通过以太网传输到windows电脑上;电脑端通过python程序接收来自以太网的数据,并将其反序列化从而获取传输的对象。由于对象序列化过程中,会对对象属性数据重新编码,在某种意义上还起到了一定程度的信息加密作用。

        话不多说,例子举来。

 例子的主要流程见上图。

  1. 我定义了一个对象player,有身高,体重,坐标x、y、z等属性,并且根据protobuf的规则将对象定义在player.proto文件中。
  2. 执行命令.\protoc.exe --nanopb_out=. player.proto,生成了C语言版本的对象定义文件player.pb.h 和player.pb.c。
  3. 执行命令.\protoc.exe --python_out=. player.proto,生成python版本的对象定义文件player_pb2.py。
  4. C程序中,集成protobuf 协议栈和对象定义文件,定义对象player,对对象赋值,序列化对象,生成序列化内容——一串神秘数字。
  5. python程序中,集成protobuf 协议栈和对象定义文件,将C语言程序生成的那串神秘数字进行反序列化,得到对象player各个属性的值。

 Note:

  • 官方protobuf工具不支持C语言,这里采用的是非官方支持protobuf协议的实现工具nanopb,下载可见附件nanopb-0.4.6-windows-x86.zip
  • protoc.exe 见附件路径 .\nanopb-0.4.6-windows-x86\generator-bin,通过不同命令参数--xxx_out=  可以生成对应语言的对象定义程序文件。
  • nanopb 附件中包含了C语言的protobuf 协议栈,需要手动集成到C语言工程中去,见附件c语言序列化编码附件c_encode_src。
  • python 工程可以通过import 直接引用protobfuf的协议栈,python 反序列化解码见附件python_decode.

      

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值