protobuf 怎么查看版本
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了protobuf 怎么查看版本相关的知识,希望对你有一定的参考价值。
protobuf版本需要在protobuf程序中查看。
在protobuf程序中查看版本步骤如下所示:
1、点击打开计算机,进入分区列表。
2、在计算机分区列表中选择protobuf程序所在的文件夹。
3、点击打开protobuf程序。
4、如图所示在protobuf程序中,即可完成protobuf版本查看。
l 标量值类型
l Optional 的字段及默认值
l 枚举
l 使用其他消息类型
l 嵌套类型
l 更新一个消息类型
l 扩展
l 包(package)
l 定义服务(service)
l 选项(option)
l 生成访问类
本指南描述了怎样使用protocolbuffer语言来构造你的protocol buffer数据,包括.proto文件语法以及怎样生成.proto文件的数据访问类。
本文是一个参考指南——如果要查看如何使用本文中描述的多个特性的循序渐进的例子,请在http://code.google.com/intl/zh-CN/apis/protocolbuffers/docs/tutorials.html中查找需要的语言的教程。
l 定义一个消息类型
先来看一个非常简单的例子。假设你想定义一个“搜索请求”的消息格式,每一个请求含有一个查询字符串、你感兴趣的查询结果所在的页数,以及每一页多少条查询结果。可以采用如下的方式来定义消息类型的.proto文件了:
message SearchRequest
required string query = 1;
optional int32 page_number = 2;
optional int32 result_per_page = 3;
SearchRequest消息格式有3个字段,在消息中承载的数据分别对应于每一个字段。其中每个字段都有一个名字和一种类型。
Ø 指定字段类型
在上面的例子中,所有字段都是标量类型:两个整型(page_number和result_per_page),一个string类型(query)。当然,你也可以为字段指定其他的合成类型,包括枚举(enumerations)或其他消息类型。
Ø 分配标识号
正如上述文件格式,在消息定义中,每个字段都有唯一的一个标识符。这些标识符是用来在消息的二进制格式中识别各个字段的,一旦开始使用就不能够再改 变。注:[1,15]之内的标识号在编码的时候会占用一个字节。[16,2047]之内的标识号则占用2个字节。所以应该为那些频繁出现的消息元素保留 [1,15]之内的标识号。切记:要为将来有可能添加的、频繁出现的标识号预留一些标识号。
最小的标识号可以从1开始,最大到229 - 1, or 536,870,911。不可以使用其中的[19000-19999]的标识号, Protobuf协议实现中对这些进行了预留。如果非要在.proto文件中使用这些预留标识号,编译时就会报警。
Ø 指定字段规则
所指定的消息字段修饰符必须是如下之一:
² required:一个格式良好的消息一定要含有1个这种字段。表示该值是必须要设置的;
² optional:消息格式中该字段可以有0个或1个值(不超过1个)。
² repeated:在一个格式良好的消息中,这种字段可以重复任意多次(包括0次)。重复的值的顺序会被保留。表示该值可以重复,相当于java中的List。
由于一些历史原因,基本数值类型的repeated的字段并没有被尽可能地高效编码。在新的代码中,用户应该使用特殊选项[packed=true]来保证更高效的编码。如:
repeated int32 samples = 4 [packed=true];
required是永久性的:在将一个字段标识为required的时候,应该特别小心。如果在某些情况下不想写入或者发送一个required的 字段,将原始该字段修饰符更改为optional可能会遇到问题——旧版本的使用者会认为不含该字段的消息是不完整的,从而可能会无目的的拒绝解析。在这 种情况下,你应该考虑编写特别针对于应用程序的、自定义的消息校验函数。Google的一些工程师得出了一个结论:使用required弊多于利;他们更 愿意使用optional和repeated而不是required。当然,这个观点并不具有普遍性。
Ø 添加更多消息类型
在一个.proto文件中可以定义多个消息类型。在定义多个相关的消息的时候,这一点特别有用——例如,如果想定义与SearchResponse消息类型对应的回复消息格式的话,你可以将它添加到相同的.proto文件中,如:
message SearchRequest
required string query = 1;
optional int32 page_number = 2;
optional int32 result_per_page = 3;
message SearchResponse
…
Ø 添加注释
向.proto文件添加注释,可以使用C/C++/java风格的双斜杠(//) 语法格式,如:
message SearchRequest
required string query = 1;
optional int32 page_number = 2;// 最终返回的页数
optional int32 result_per_page = 3;// 每页返回的结果数
Ø 从.proto文件生成了什么?
当用protocolbuffer编译器来运行.proto文件时,编译器将生成所选择语言的代码,这些代码可以操作在.proto文件中定义的消息类型,包括获取、设置字段值,将消息序列化到一个输出流中,以及从一个输入流中解析消息。
² 对C++来说,编译器会为每个.proto文件生成一个.h文件和一个.cc文件,.proto文件中的每一个消息有一个对应的类。
² 对Java来说,编译器为每一个消息类型生成了一个.java文件,以及一个特殊的Builder类(该类是用来创建消息类接口的)。
² 对Python来说,有点不太一样——Python编译器为.proto文件中的每个消息类型生成一个含有静态描述符的模块,,该模块与一个元类(metaclass)在运行时(runtime)被用来创建所需的Python数据访问类。
你可以从如下的文档链接中获取每种语言更多API。http://code.google.com/intl/zh-CN/apis/protocolbuffers/docs/reference/overview.html
l 标量数值类型
一个标量消息字段可以含有一个如下的类型——该表格展示了定义于.proto文件中的类型,以及与之对应的、在自动生成的访问类中定义的类型:
.proto类型
Java 类型
C++类型
备注
double
double
double
float
float
float
int32
int
int32
使用可变长编码方式。编码负数时不够高效——如果你的字段可能含有负数,那么请使用sint32。
int64
long
int64
使用可变长编码方式。编码负数时不够高效——如果你的字段可能含有负数,那么请使用sint64。
uint32
int[1]
uint32
Uses variable-length encoding.
uint64
long[1] uint64 Uses variable-length encoding.
sint32
int
int32
使用可变长编码方式。有符号的整型值。编码时比通常的int32高效。
sint64
long
int64
使用可变长编码方式。有符号的整型值。编码时比通常的int64高效。
fixed32
int[1]
uint32
总是4个字节。如果数值总是比总是比228大的话,这个类型会比uint32高效。
fixed64
long[1]
uint64
总是8个字节。如果数值总是比总是比256大的话,这个类型会比uint64高效。
sfixed32
int
int32
总是4个字节。
sfixed64
long
int64
总是8个字节。
bool
boolean
bool
string
String
string
一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本。
bytes
ByteString
string
可能包含任意顺序的字节数据。
你可以在文章http://code.google.com/apis/protocolbuffers/docs/encoding.html 中,找到更多“序列化消息时各种类型如何编码”的信息。
l Optional的字段和默认值
如上所述,消息描述中的一个元素可以被标记为“可选的”(optional)。一个格式良好的消息可以包含0个或一个optional的元素。当解 析消息时,如果它不包含optional的元素值,那么解析出来的对象中的对应字段就被置为默认值。默认值可以在消息描述文件中指定。例如,要为 SearchRequest消息的result_per_page字段指定默认值10,在定义消息格式时如下所示:
optional int32 result_per_page = 3 [default = 10];
如果没有为optional的元素指定默认值,就会使用与特定类型相关的默认值:对string来说,默认值是空字符串。对bool来说,默认值是false。对数值类型来说,默认值是0。对枚举来说,默认值是枚举类型定义中的第一个值。
l 枚举
当需要定义一个消息类型的时候,可能想为一个字段指定某“预定义值序列”中的一个值。例如,假设要为每一个SearchRequest消息添加一个 corpus字段,而corpus的值可能是UNIVERSAL,WEB,IMAGES,LOCAL,NEWS,PRODUCTS或VIDEO中的一个。 其实可以很容易地实现这一点:通过向消息定义中添加一个枚举(enum)就可以了。一个enum类型的字段只能用指定的常量集中的一个值作为其值(如果尝 试指定不同的值,解析器就会把它当作一个未知的字段来对待)。在下面的例子中,在消息格式中添加了一个叫做Corpus的枚举类型——它含有所有可能的值 ——以及一个类型为Corpus的字段:
message SearchRequest
required string query = 1;
optional int32 page_number = 2;
optional int32 result_per_page = 3 [default = 10];
enum Corpus
UNIVERSAL = 0;
WEB = 1;
IMAGES = 2;
LOCAL = 3;
NEWS = 4;
PRODUCTS = 5;
VIDEO = 6;
optional Corpus corpus = 4 [default = UNIVERSAL];
参考技术B protoc --version
如何强制 CMake 使用系统上安装的特殊版本的 Protobuf?
【中文标题】如何强制 CMake 使用系统上安装的特殊版本的 Protobuf?【英文标题】:How to force CMake to use a special version of Protobuf installed on system? 【发布时间】:2021-01-06 21:48:39 【问题描述】:我想将Protobuf_INCLUDE_DIRS
设置为我选择的目录,但是我不知道该怎么做。
$ locate FindProtobuf.cmake
/usr/share/cmake-3.16/Modules/FindProtobuf.cmake
我可以看到在FindProtobuf.cmake
,我们有这些:
if(Protobuf_FOUND)
set(Protobuf_INCLUDE_DIRS $Protobuf_INCLUDE_DIR)
endif()
我希望这里设置为第二个选项:
$ which -a protoc
/home/mona/anaconda3/bin/protoc
/usr/local/bin/protoc
然而,它被设置为第一个选项/home/mona/anaconda3/bin/protoc
,尽管在 ~/.bashrc 中强制它为第二个选项:/usr/local/bin/protoc
,使用以下命令:alias protoc=/usr/local/bin/protoc
我的程序需要的版本是 3.6.1,别名 protoc=/usr/local/bin/protoc 保证了这一点。但是,ProtobufCMake 强制路径为 /home/mona/anaconda3/bin/protoc
并且该版本为 3.13.0。
关于我面临的问题。我正在使用 openpose 并在 Ubuntu 20.04 中安装它,我使用的是 CMake。它要求 protobuf 版本为 3.6.1。
更多信息在这里https://github.com/CMU-Perceptual-Computing-Lab/openpose/issues/1817
以下是消息:
CMake Error at /usr/share/cmake-3.16/Modules/FindProtobuf.cmake:469 (file):
file STRINGS file "/usr/include/google/protobuf/stubs/common.h" cannot be
read.
Call Stack (most recent call first):
CMakeLists.txt:429 (find_package)
CMake Error at /usr/share/cmake-3.16/Modules/FindProtobuf.cmake:475 (math):
math cannot parse the expression: " / 1000000": syntax error, unexpected
exp_DIVIDE (2).
Call Stack (most recent call first):
CMakeLists.txt:429 (find_package)
CMake Error at /usr/share/cmake-3.16/Modules/FindProtobuf.cmake:476 (math):
math cannot parse the expression: " / 1000 % 1000": syntax error,
unexpected exp_DIVIDE (2).
Call Stack (most recent call first):
CMakeLists.txt:429 (find_package)
CMake Error at /usr/share/cmake-3.16/Modules/FindProtobuf.cmake:477 (math):
math cannot parse the expression: " % 1000": syntax error, unexpected
exp_MOD (2).
Call Stack (most recent call first):
CMakeLists.txt:429 (find_package)
CMake Warning at /usr/share/cmake-3.16/Modules/FindProtobuf.cmake:499 (message):
Protobuf compiler version 3.13.0 doesn't match library version
ERROR.ERROR.ERROR
Call Stack (most recent call first):
CMakeLists.txt:429 (find_package)
【问题讨论】:
【参考方案1】:不知道我想在上面做什么,但是让 CMake 为 OpenPose 工作的一个技巧是使用 Python venv 并在 ~/.bashrc 中注释 anaconda python 激活行:
现在,cmake-gui ..
不会抛出错误:
GCC detected, adding compile flags
GCC detected, adding compile flags
Building with CUDA.
CUDA detected: 10.1
Added CUDA NVCC flags for: sm_75
cuDNN not found
Found gflags (include: /usr/include, library: /usr/lib/x86_64-linux-gnu/libgflags.so)
Found glog (include: /usr/include, library: /usr/lib/x86_64-linux-gnu/libglog.so)
Caffe will be downloaded from source now. NOTE: This process might take several minutes depending
on your internet connection.
Caffe has already been downloaded.
HEAD is now at 1807aada Added Ampere arch's (CUDA11)
Caffe will be built from source now.
Download the models.
Downloading BODY_25 model...
Model already exists.
Not downloading body (COCO) model
Not downloading body (MPI) model
Downloading face model...
Model already exists.
Downloading hand model...
Model already exists.
Models Downloaded.
Configuring done
我在 ~/.bashrc 中有这个:
# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
##__conda_setup="$('/home/mona/anaconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
##if [ $? -eq 0 ]; then
## eval "$__conda_setup"
##else
## if [ -f "/home/mona/anaconda3/etc/profile.d/conda.sh" ]; then
## . "/home/mona/anaconda3/etc/profile.d/conda.sh"
## else
## export PATH="/home/mona/anaconda3/bin:$PATH"
## fi
##fi
并在 Ubuntu 20.04 中安装了以下内容:
$ sudo apt-get install python3
$ sudo apt-get install python3-venv
另外,在 ~/.bashrc 中执行此操作并获取它:alias python=python3
$ python -m venv ~/venv/openpose
$ source ~/venv/openpose/bin/activate
【讨论】:
以上是关于protobuf 怎么查看版本的主要内容,如果未能解决你的问题,请参考以下文章
如何强制 CMake 使用系统上安装的特殊版本的 Protobuf?