栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

Linux C++, Protobuf转Json ,转String 示例详解

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Linux C++, Protobuf转Json ,转String 示例详解

Linux C++, Protobuf转Json ,转String 示例详解

本文从如下几个方面,对Proto结构的定义、编程以及存储进行详细说明:

  • Proto文件定义
  • 生成proto结构对应的读、写接口
  • proto 与 string 相互转换
  • proto与json相互转换
  • 数据库存取proto结构
  • (1)以json格式对proto结构信息进行存取
  • (2)以自定义类型 对proto结构信息进行存取
1、Proto文件定义 1.1示例定义:

定义 test.proto 文件,文件内容为:

syntax = "proto3";
package SDF;

message ADF_TrafficControlAttr
{
  // 管制原因
  enum TrafficCtlType{
    UNKNOWN_INDUCED = 0; //未知或其他
    ROAD_INDUCED = 1; //道路原因
    ADMIN_INDUCED = 2; //管理员原因
  };
  enum TrafficCtlMode{
    UNKNOWN = 0; //未知或其他
    SPEED_LIMIT = 1; //限制速度
    NOPASSING = 2; //禁止通行
  };
  //受管制车型
  enum AffectedType{
    ALL = 0; //所有车辆
    AUTO = 1; // 所有自动驾驶车辆
    MANUAL = 2; // 所有有人车辆
  };
  TrafficCtlType ctrlType = 1;   //
  AffectedType affectedType = 2;   //syntax = "proto3";
  TrafficCtlMode trafficCtlMode = 3; //限制类型     #改
  repeated string listOfAffected = 4; //受管制清单     #增删改
  int32 speedLimitValue = 5; //限制速
}

message EDF_TrafficControl
{
  string eventID = 1; //事件ID    #增
  ADF_TrafficControlAttr eventAttr = 2; //事件属性     #改2
  string warningMessage = 3; //预警提示     #增删改
}
1.2 格式说明

定义消息的语法很简单,message 关键字后跟上消息名称:

message xxx
 {
 
}

定义 message 具有的属性,有如下关键字:

(1)字段规则
required -> 字段只能也必须出现 1 次
optional -> 字段可出现 0 次或1次
repeated -> 字段可出现任意多次(包括 0)

(2)字段类型
int32、int64、sint32、sint64、string、32-bit …

(3)字段编号
范围:0 ~ 536870911(除去 19000 到 19999 之间的数字)

(4)定义格式:
字段规则 类型 名称 = 字段编号;

2、生成proto结构对应的读、写接口

可通过如下命令生成相应的接口代码:

protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/xxx.proto
  • $SRC_DIR: .proto 所在的源目录
  • --cpp_out: 生成 c++ 代码
  • $DST_DIR: 生成代码的目标目录
  • xxx.proto: 要针对哪个 proto 文件生成接口代码

再如本例:

注意:首先cd 到test.proto所在目录。

protoc -I=./ --cpp_out=./ ./test.proto

执行命令后,会在当前目录下生成test.pb.cc、test.pb.h文件。

C 或 C++程序中,直接使用生成的这两个即可。

3、proto 与 string 相互转换
在 .proto 文件中定义了数据结构,这些数据结构是面向开发者和业务程序的,并不面向存储和传输。当需要把这些数据进行存储或传输时,就需要将这些结构数据进行序列化、反序列化以及读写。
#include 
#include 
#include "test.pb.h"
 
using namespace std;

void SetProtoValue(SDF::EDF_TrafficControl &trafficContolInfo)
{
  SDF::EDF_TrafficControl trafficContolInfo;
	
  auto eventAttr = trafficContolInfo.mutable_eventattr();
  eventAttr->set_ctrltype(SDF::ADF_TrafficControlAttr::ROAD_INDUCED);
  eventAttr->set_affectedtype(SDF::ADF_TrafficControlAttr::MANUAL);
  eventAttr->set_trafficctlmode(SDF::ADF_TrafficControlAttr::SPEED_LIMIT);
  eventAttr->add_listofaffected("affectedItem1");
  eventAttr->add_listofaffected("affectedItem2");
  eventAttr->set_speedlimitvalue(60);

  trafficContolInfo.set_warningmessage("warningMessage_888");
} 

int main(int argc, char** argv)
{
  std::string str_protoString = "";
  
  SDF::EDF_TrafficControl trafficContolInfo;
  SetProtoValue(trafficContolInfo);
	
	//Proto结构 转 字符串
	std::string str_protoString = trafficContolInfo.SerializeAsString();

  //字符串 转 Proto结构
  SDF::EDF_TrafficControl trafficContolInfoNew;
  trafficContolInfoNew.ParseFromString(str_protoString)

}

4、proto与json相互转换
#include 
#include 
#include   //是用json转换工具
#include "test.pb.h"
 
using namespace std;

void SetProtoValue(SDF::EDF_TrafficControl &trafficContolInfo)
{
  SDF::EDF_TrafficControl trafficContolInfo;
	
  auto eventAttr = trafficContolInfo.mutable_eventattr();
  eventAttr->set_ctrltype(SDF::ADF_TrafficControlAttr::ROAD_INDUCED);
  eventAttr->set_affectedtype(SDF::ADF_TrafficControlAttr::MANUAL);
  eventAttr->set_trafficctlmode(SDF::ADF_TrafficControlAttr::SPEED_LIMIT);
  eventAttr->add_listofaffected("affectedItem1");
  eventAttr->add_listofaffected("affectedItem2");
  eventAttr->set_speedlimitvalue(60);

  trafficContolInfo.set_warningmessage("warningMessage_888");
} 

int main(int argc, char** argv)
{
  std::string str_protoJsonString = "";
  
  SDF::EDF_TrafficControl trafficContolInfo;
  SetProtoValue(trafficContolInfo);
	
	//Proto结构 转 Json字符串
  google::protobuf::util::JsonPrintOptions options;
  options.add_whitespace = true;
  options.always_print_primitive_fields = true;
  options.preserve_proto_field_names = true;  
  if(!MessageToJsonString(traffic_control, &str_protoJsonString, options).ok())
  {//parse traffic_control to json string
    std::cerr << " MessageToJsonString() convert failed" << std::endl;
  }	

  //Json字符串 转 Proto结构
  SDF::EDF_TrafficControl trafficContolInfoNew;
 if(!google::protobuf::util::JsonStringToMessage(str_protoJsonString, &trafficContolInfoNew).ok())
 {
      printf("MessageToJsonString() convert failed");
  }


}

5、数据库存取proto结构 5.1 以json格式对proto结构信息进行存取

数据库存取过程中,除了需要将数据库字段类型定义为json或jsonb外,增、删、改数据库的方法,均与普通字符串类型一致。
json会输出和输入完全相同的文本,而jsonb 则不会保留语义上没有意义的细节(例如空格)。

PostgresSQL从9.2版本开始支持JSON数据类型,并提供很多函数和操作符维护json数据。

本文以postgres数据库为例,进一步说明 转换为json格式后的 proto结构,在数据库中的格式定义及存取方式。

5.1.1 建表:jsonb 或 json 字段类型
create table if not exists test_table(event_id serial not null PRIMARY KEY, msg_content_jsonb jsonb, msg_content_json json, time_stamp  timestamptz not null);
5.1.2 插入数据
insert into test_table(msg_content_jsonb, msg_content_json) values(str_protoJsonString, str_protoJsonString, NOW());
5.1.3 查询数据
select event_id, msg_content_jsonb, msg_content_json from test_table;

关于Postgres存储 Json类型字段的详细说明,详见:
《 Postgres - JSON 类型实例示例》
https://aduandniuniu.blog.csdn.net/article/details/125304811?spm=1001.2014.3001.5502

关于Postgres数据库字段 类型定义,详见:
《Postgres - 数据库字段 类型定义》

https://aduandniuniu.blog.csdn.net/article/details/125305244?spm=1001.2014.3001.5502#t7

5.2以自定义类型 对proto结构信息进行存取

也可以通过自定义类型的方式,为proto结构定义对应的字段进行存取。

比如:

create type TrafficCtlType as ENUM(
    'UNKNOWN_INDUCED' ,
    'ROAD_INDUCED',
    'ADMIN_INDUCED'
);

create type TrafficCtlMode as ENUM(
    'UNKNOWN' ,
    'SPEED_LIMIT',
    'NOPASSING'
);

create type AffectedType as ENUM(
    'ALL' ,
    'AUTO',
    'MANUAL'
);

create type ADF_TrafficControlAttr as(
    ctrlType TrafficCtlType, 
    affectedType AffectedType, 
    trafficCtlMode TrafficCtlMode, 
    listOfAffected text[], 
    speedLimitValue integer 
);
    
    
create table traffic_control_ctrl(
    eventID serial not null PRIMARY KEY, 
    eventAttr ADF_TrafficControlAttr,
    warningMessage varchar(128),
    status RecordStatus
);

关于 Postgres数据库自定义类型 的增、删、改、查 ,更为详细的说明,详见:

《Postgres - 自定义类型》
https://aduandniuniu.blog.csdn.net/article/details/125244683?spm=1001.2014.3001.5502

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1010018.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号