请支持原创~~
0. 前言
Protobuf是一种灵活高效可序列化的数据协议,相于XML,具有更快、更简单、更轻量级等特性。支持多种语言,只需定义好数据结构,利用Protobuf框架生成源代码,就可很轻松地实现数据结构的序列化和反序列化。一旦需求有变,可以更新数据结构,而不会影响已部署程序。
Protobuf 是一个小型的软件框架,也可以称为protocol buffer 语言,带着疑问会发现Proto 有很多需要了解:
- Proto 文件书写格式,关键字package、option、Message、enum 等含义和注意点是什么?
- 消息等嵌套如何使用?实现的原理?
- Proto 文件对于不同语言的编译,和产生的obj 文件的位置?
- Proto 编译后的cc 和java 文件中不同函数的意义?
- 如何实现*.proto 到*.java、*.h、*.cc 等文件?
- 数据包的组成方式、repeated 的含义和实现?
- Proto 在service和client 的使用,在java 端和native 端如何使用?
- 与xml 、json 等相比时间、空间上的比较如何?
- ...
说明:
- 本文主要分析protobuf 在java 和c++ 中的引用,其他语言暂时不做过多阐述;
- 本文很多地方的代码引用将采用Android AOSP 中 windowmanagerservie.proto为例;
- 本文从最基本的开始剖析、总结,上面说Protobuf 是个小型的软件框架,但是当真正进入使用时,会发现很多需要注意的地方。所以,后面持续补充、长期更新;
- 由于时间原因,希望最后尽可能地让这个知识点完整!!
1. proto 特点
其中高效性从网上copy 了一个表格,注明:本人没有验证过(不懂Json),仅供参考
序列化时间效率对比:
数据格式 | 1000条数据 | 5000条数据 |
---|
Protobuf | 195ms | 647ms | Json | 515ms | 2293ms |
序列化空间效率对比:
数据格式 | 5000条数据 |
---|
Protobuf | 22MB | Json | 29MB |
2. proto 支持语言
2.? proto 语法
2.1 syntax
syntax = "proto2";
用以制定语法版本,proto2 或proto3
2.2 import
import "frameworks/base/core/proto/android/view/surface.proto";
import "frameworks/base/core/proto/android/view/windowlayoutparams.proto";
import "frameworks/base/core/proto/android/privacy.proto";
用以引入其他文件中的message、enum等
注意,import 引用的proto 文件在编译成java 和c++ 是不同处理
- java 中是忽略该import,而是采用完全引用;
- c++ 中将import 的proto 文件,换成引用头文件形式;
2.3 package
package com.android.server.wm;
用以指定proto 的包名,如果其他的proto 文件import 后,可以根据这个包名进行引用,也可以通过package 确定编译后的文件的路径。
例如,
package foo.bar;
message Open { ... }
引用的时候:
message Foo {
...
required foo.bar.Open open = 1;
...
}
2.3.1 package 在c++ 中引用
这里是proto 中的引用,当编译称c++ 文件时,这里的package 则会被编译称namespace。如上面的例子,foo.bar 在编译称c++ 后,Foo 会编译成class,而Foo 类位于foo::bar 这个namespace 中。
2.3.2 package 在java 中引用
package 在java 中的引用稍微有些不同,因为对于java 文件可以在proto 中通过java_package 进行修改,例如:
package foo.bar;
option java_package = "com.example.foo.bar";
message Open { ... }
The?java_package ?option is provided because normal?.proto ?package ?declarations are not expected to start with a backwards domain name.
2.3.3 pacakge 在python/go 中引用
package 在python 或 go 中是被忽略的,它们有各自的规则
2.4 message
2.5 enum
2.6 service
参考:
https://blog.csdn.net/weixin_45519413/article/details/113356501
https://juejin.cn/post/6844903582743920648
|