protobuf中的message数据结构简明教程

举报
蒲公英 发表于 2021/08/02 11:19:51 2021/08/02
【摘要】 介绍如何对如何对protobuf中的message结构进行数据操作。关于protobuf和message数据结构的概念介绍,来源于https://www.jianshu.com/p/b723053a86a6和https://zhuanlan.zhihu.com/p/25174418 。

参考资料:https://www.jianshu.com/p/b723053a86a6   // protobuf定义

https://zhuanlan.zhihu.com/p/25174418    // message结构描述

Protobuf是什么

Protobuf实际是一套类似Json或者XML的数据传输格式和规范,用于不同应用或进程之间进行通信时使用。通信时所传递的信息是通过Protobuf定义的message数据结构进行打包,然后编译成二进制的码流再进行传输或者存储。

message结构:

Protobuf通过定义message数据结构来进行使用。

  • 在一个proto文件中可以包含多个message定义,message之间可以互相引用,message还可以嵌套message和枚举类;
  • 一个message通常包含一至多个字段;
  • 每个字段包含以下几个部分:字段描述符(可选)、字段类型、字段名称和字段对应的Tag

字段描述符

字段描述符用于描述字段出现的频率,有以下两个可选值:

  • singular:表示出现0次或1次;如果没有声明描述符,默认为singular
  • repeated:表示出现0次或多次;

字段类型

  • 基本数据类型:包括doublefloatboolstringbytesint32int64uint32uint64sint32sint64fixed32fixed64sfixed32sfixed64
  • 引用其他message类型;
  • 枚举类型:对于枚举类型,protobuf有个约束:枚举的第一项对应的值必须为0

 

如下为一个message结构例子:

packeage MxTools;
message MxpiClass

{

    repeated MxpiMetaHeader headerVec = 1;

    int32 classId = 2;

    string className = 3;

    float confidence = 4;

}



message MxpiMetaHeader

{

    string parentName = 1;

    int32 memberId = 2;

    string dataSource = 3;

}

 

  • MxpiClass这个数据结构中,嵌套了另一个message类型(MxpiMetaHeader)
  • repeated声明该字段是可出现多次的。
  • 每个message里面的字段都有对应的Tag值,且Tag必须是唯一数字。Tag主要用于说明字段在二进制文件的对应关系,一旦指定字段为对应的Tag,不应该在后续进行变更;

如何对message数据结构进行数据操作

    下面,我们以MxpiClass为例子说明如何对message数据结构进行操作。

代码如下:

int main(int argc, char* argv[])

{

    MxpiClass  mxpiClass;



    // 对int类型字段赋值

    mxpiClass.set_classid(1);  //



    // 对string类型字段赋值

    mxpiClass.set_classname("MyMxpiClass");



    // 对repeated 类型字段赋值的方法.

    // 首先需要通过add_headervec()创建一个header_1,

    // 通过对header_1的赋值来实现赋值操作

    // 注意:此时的header_1是指针

    MxpiMetaHeader* header_1 = mxpiClass.add_headervec();

    header_1->set_datasource("myDataSource_1");

    header_1->set_memberid(1);

    // 对repeated类型数据的查看,查看第一个headerVec

    cout << mxpiClass.headervec(0).datasource()<<endl;

    cout << mxpiClass.headervec(0).memberid()<<endl;



    // 添加第二个headerVec

    MxpiMetaHeader* header_2 = mxpiClass.add_headervec();

    header_2->set_datasource("myDataSource_2");

    header_2->set_memberid(2);

    // 查看第二个headerVec

    cout << mxpiClass.headervec(1).datasource()<<endl;

    cout << mxpiClass.headervec(1).memberid()<<endl;

    // 输出mxpiClass的数据结构

    cout<< "MxpiClass {\n"<<mxpiClass.DebugString() <<"}"<<endl;

    return 0;

}

 

最后,采用DebugString()方法,显示mxpiClass的数据结构如下:

MxpiClass {

    headerVec {

    memberId: 1

    dataSource: "myDataSource_1"

    }

    headerVec {

    memberId: 2

    dataSource: "myDataSource_2"

    }

    classId: 1

    className: "MyMxpiClass"

}

 

嵌套message数据结构的数据操作:如果一个message结构嵌套了另一个message结构,如下所示:

message MxpiVision                         

{

    repeated MxpiMetaHeader headerVec = 1; 

    MxpiVisionInfo visionInfo = 2;

    MxpiVisionData visionData = 3;

}



message MxpiVisionData              

    uint64 dataPtr = 1;             

    int32 dataSize = 2;

    uint32 deviceId = 3;

    MxpiMemoryType memType = 4;

    uint64 freeFunc = 5;            

    bytes dataStr = 6;              

}
enum MxpiMemoryType {

    MXPI_MEMORY_HOST = 0;

    MXPI_MEMORY_DEVICE = 1;

    MXPI_MEMORY_DVPP = 2;

}

 

MxpiVision中嵌套了MxpiVsionData,如下代码示例如何对MxpiVsionData进行赋值。

int main(int argc, char* argv[])

{

    MxpiVision mxpiVsion;

    // 使用mutable方法新建一个MxpiVisionData数据类型,通过对Data赋值实现。

    MxpiVisionData* Data = mxpiVsion.mutable_visiondata();

    Data->set_dataptr(123456);

    Data->set_deviceid(1);

    // 对enum类型的字段赋值示例

    Data->set_memtype(MXPI_MEMORY_HOST);  

    return 0;

}

总结:

  1. 对于singular类的字段:
  • 基本数据类型的字段,通过“set_字段名()”方式进行赋值。
  • 对于嵌套的message字段,通过“mutable_字段名()”,新建一个该类数据结构,然后进行赋值。
  1. repeated字段:
  • 基本数据类型,通过“add_字段名()”,进行赋值,例如add_num(2)(numint型字段)
  • 对于嵌套的message字段,通过“add_字段名()”,添加一个该类的数据结构,然后进行赋值。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。