Google protobuf开发者文档笔记

本文档笔记介绍了Google protobuf的编码格式、编译器生成的C++代码、oneof特性、解析和序列化及反射等核心概念。重点讨论了protobuf的向后兼容性、字段编码方式、消息结构、编码优化以及如何使用protobuf编译器生成代码。同时,解释了protobuf如何处理有符号整数、字符串、嵌套消息和重复字段,并提供了序列化和反序列化的API使用方法。
摘要由CSDN通过智能技术生成

开发者文档笔记

  1. protobuf向后兼容,增加新字段不影响旧的代码的解析过程,旧代码会忽略它
  2. 每个字段后面的数字(tag)用来在序列化后的二进制中标识这个字段。在1-15的tag占用1个字节(wiretype占3位,最高有效位被占用),所以常用字段要设置较小的tag
  3. 谨慎使用required,使用requied但是没有传值的话,可能message会被拒绝或扔掉,所以应该在应用层代码中自己校验完整性而不是使用required。
  4. Reserved field:当删除.proto文件中的某字段时,这个字段的tag number 又能被继续使用,但是当其他用户引入了旧版本的.proto文件,就可能引起tag number冲突,所以推荐在删除某字段时,把该field的tag number和name都设置为reserved field,这样别人想再次使用时,编译器会报错。
  5. Protocol buffer编译器会根据.proto文件生成get or set field value的函数,从一个输入流中parse 得到message 或把message序列化到输出流的函数。
  6. 更新一个消息类型的准则.
    • 不要改变已经存在的域的tag
    • 任何添加的新字段应该是optional或者repeated类型.
    • Non-Required字段可以被去掉,只要tag number不要被reuse
    • int32, uint32, int64, uint64, and bool are all compatible
    • sint32 and sint64 are compatible
    • Embedded Message和bytes可以转换
  7. import definitions
    当需要其它proto文件中的定义时,默认情况下import该文件,但不支持递归import。当把一个proto文件移到另一个位置时,不需要修改每一处对该proto文件的import,只需要在旧proto里用import public 指向新的位置,这样对旧proto的import就能依赖到新的proto。import文件的搜索路径由–proto_path标志指定

信息编码格式

基于128位varints编码

  1. Varints是一种用一个或更多字节序列化整数的方式
  2. Varints中的每个字节的最高有效位用来代表是否这个整数还有后续的字节,所以除了最后一个字节外,所有的字节的最高有效位都被设置。
  3. 从一个varints编码得到原始整数的方法:
    比如300的编码为1010 1100 0000 0010
    两个字节分别为 10101100 00000010
    都去掉最高有效位 0101100 0000010
    因为varints是把最低有效的字节组(去掉最高有效位后的7个字节为一个字节组,用来表示整数的值)排在前面,所以这里需要翻转一下,变为:
    00000100101100, 即300.

消息结构

  1. 消息编码的时候,字段的field number(在.proto文件定义)和wire type(提供接下来的值所占长度的信息,比如wire type为0,代表这个值是int32类型,占4个字节,具体wire type的种类见https://developers.google.com/protocol-buffers/docs/encoding#structure)作为key,字段的值作为value,key+value一起存在编码后的数据中。Key是一个varints,按(filednumber<<3|wire type)的方式存储,也就是说,key的最低三位就是wire type。
  2. 有符号整数:当值为负数时,有符号整数(sint32,sin64)和int32,int64不同,当使用int32和int64时,编码后的varints为10字节长,它被对待成一个很大的无符号整数。当使用sint32和sint64时,结果varints使用zigzag编码,这更有效率。
  3. zigzag编码把有符号整数映射为无符号整数,使得有较小绝对值的数有较短的varints编码。
    zigzag编码,每个n被映射为(n<<1)^(n>>31),这里是算术右移(右移时填充符号位),所以对负数而言,(n>>31)时全1,对正数而言时全0.
  4. 非varint数字类型:double和fixed64为64位,float和fixed32为32位
  5. String类型:value为字符串的长度后面跟着实际的字符串数据
    嵌套消息:被当作和string一样来看待,tag+wire type 后面跟这个嵌套消息的字节数,然后跟嵌套消息的编码
  6. [packed = true]选项:使repeated字段更有效的编码.

编译器生成c++代码

  1. 使用‘—cpp_out=dir’参数调编译器,编译器会在dir生成c++代码。
  2. 编译器会把.proto替换成.pb.h和.pb.cÿ
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值