目录
Google Protobuf简介
Google Protobuf是一种轻量级的数据交换格式,它使用类似XML的结构化数据描述语言来定义数据结构,并使用二进制格式进行序列化和反序列化。通过使用Protobuf,可以使得不同语言和平台之间的数据交换变得更加简单和高效。
在Google Protobuf中,数据结构的定义以.proto文件的形式进行,每个.proto文件定义了一个或多个message类型,每个message类型又由一个或多个字段组成。字段可以是多种类型,包括基本类型(如int、float、bool等)、字符串、枚举、嵌套message等。在.proto文件中,还可以定义一些服务(service),服务定义了一组RPC方法,用于实现远程过程调用。
使用Google Protobuf进行数据交换的过程如下:
根据.proto文件生成对应语言的代码文件,例如C++、Java、Python等。
在代码中创建message类型的实例,并设置其各个字段的值。
将message类型的实例序列化为二进制格式的数据流,可以将其传输给其他进程或存储在磁盘上。
另一个进程或系统可以将接收到的二进制数据流反序列化为message类型的实例,然后读取其中的字段值。
相比于XML和JSON等其他数据交换格式,Google Protobuf具有更小的序列化后的数据体积和更快的序列化和反序列化速度。同时,Protobuf还支持数据升级和向后兼容等高级功能。因此,Google Protobuf在分布式系统、网络通信、机器学习等领域被广泛应用。
.proto文件的作用
.proto文件是Google Protobuf的核心文件之一,用于定义数据结构、服务和消息格式。.proto文件是一种结构化数据格式,类似于XML或JSON,但具有更高的效率和可扩展性。通过定义.proto文件,可以使用Google Protobuf工具生成多种编程语言的代码,从而快速地将结构化数据集成到不同的应用程序中。
.proto文件中可以定义多个message类型、服务类型和枚举类型。每个message类型可以由多个字段组成,每个字段可以是基本类型(如整数、字符串、布尔值等)、枚举类型或其他message类型。每个字段都需要指定一个唯一的编号,用于在序列化和反序列化时标识字段。repeated关键字表示该字段可以重复出现。服务类型定义了一组RPC方法,用于实现远程过程调用。枚举类型定义了一组常量值。
通过.proto文件定义数据结构和服务格式,可以将这些结构化数据序列化为二进制数据流,然后在不同的系统之间进行传输和存储。同时,通过使用各种支持Google Protobuf的编程语言,可以轻松地将序列化数据反序列化为具体的数据类型,并进行各种操作和处理。
总之,.proto文件是Google Protobuf的重要组成部分,是一种简单、高效、可扩展的数据格式,可以帮助开发人员更快地构建高效、可扩展的分布式应用程序。
编写.proto文件
syntax = "proto3";
package ObjectDetectResultTool;
//信息头:
message MxpiMetaHeader
{
string parentName = 1;
int32 memberId = 2;
string dataSource = 3;
}
//对于单帧图像来说:
message ObjectAdditionalInfo
{
repeated MxpiMetaHeader headerVec = 1;
//通道号
int32 channelNumber=2;
//种类号:出现次数;如:0:7,67:4
string objnumAndshowTime = 3;
//时间戳
int32 timestamp = 4;
}
//对于一个batch的图像来说(最外层必带这一层):
message ObjectAdditionalInfoList
{
repeated ObjectAdditionalInfo infos = 1;
}
在.proto文件中,可以定义多个message类型、服务类型和枚举类型。每个message类型可以由多个字段组成,每个字段可以是基本类型(如整数、字符串、布尔值等)、枚举类型或其他message类型。每个字段都需要指定一个唯一的编号,用于在序列化和反序列化时标识字段。repeated关键字表示该字段可以重复出现。服务类型定义了一组RPC方法,用于实现远程过程调用。枚举类型定义了一组常量值。
需要注意的是,每个.proto文件都应该为一个独立的语义单元,不应该依赖其他.proto文件中的定义。同时,字段编号必须唯一并且不能重复出现,否则会导致序列化和反序列化时出现错误。
使用.proto文件生成对应的python文件及c++文件
c++及python版本的相关文件:其中PROTOBUF_PROTOC_EXECUTABLE位于mxVision-3.0.0/opensource/bin/protoc。
EXECUTE_PROCESS(
COMMAND ${
PROTOBUF_PROTOC_EXECUTABLE} ${
PROTO_FLAGS} --cpp_out=${
PROJECT_SOURCE_DIR} ${
PROJECT_SOURCE_DIR}/ObjectDetectResultTool.proto
COMMAND ${
PROTOBUF_PROTOC_EXECUTABLE} ${
PROTO_FLAGS} --python_out=${
PROJECT_SOURCE_DIR} ${
PROJECT_SOURCE_DIR}/ObjectDetectResultTool.proto
WORKING_DIRECTORY ${
CMAKE_CURRENT_SOURCE_DIR}
)
生成的C++和Python代码中都包含message类型、服务类型和枚举类型的定义,以及序列化和反序列化函数等。在使用生成的代码时,需要将对应的库文件链接到项目中(对于C++代码)或将对应的Python文件导入到项目中(对于Python代码)。
执行编译后将生成下列文件:
并编译生成独立的.so文件。该.so文件在插件生成时也需被引用,在程序获取插件结果时也需被引用,因此不能被源码编译进插件内。
完整的cmakelist文件:
cmake_minimum_required(VERSION 3.5.1)
project(ProtoFile)
set(TARGET_LIBRARY objectdetectresulttool)
# Compile options
add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0 )
add_definitions(-Dgoogle=mindxsdk_private)
add_compile_options(-std=c++11 -fPIC -fstack-protector-all -pie -Wno-deprecated-declarations)
set(MX_SDK_HOME /home/HwHiAiUser/mxVision-3.0.0)
if (EXISTS ${
MX_SDK_HOME})
set(PROTOBUF_FOUND TRUE)
set(PROTOBUF_PROTOC_EXECUTABLE ${
MX_SDK_HOME}/opensource/bin/protoc)
set(PROTOBUF_INCL