使用方法。git上下载protobuf,克隆至本地,git地址直接在码云上拉取
protobuf: https://github.com/protocolbuffers/protobuf.git
缺少googleTest和abseil文件分别在git上拉取,直接al lbuild编译
创建proto文件
syntax = "proto3"
optin optimize_for = LITE_RUNTIME;
message ErrorInfo
{
int id = 1;
int errorCod = 3;
}
optimize_for是文件级别的选项,Protocol Buffer定义三种优化级别SPEED/CODE_SIZE/LITE_RUNTIME。缺省情况下是SPEED。
SPEED:生成代码运行效率高,但由此生成的代码编译后会占用更多空间。
CODE_SIZE:与SPEED相反,代码运行效率低,但生成后的代码会占用更少的空间,用于资源有限平台,如Mobile。
LITE_RUNTIME:生成代码执行效率高,同时代码编译后所占空间也是非常少。这是牺牲ProtoBuffer提供的反射功能为代价的。因此我们在C++中链接Protocol Buffer库时仅需要链接libporotobuf-lited,而非libprotobuf。
对于LITE_MESSAGE选项而言,其生成的代码均将继承自MessageLite,而非Message。
PB的主要优点是它比JSON消耗的内存少,而且读写速度更快。protobuf对象还是不可改变的,如果要确保对象的值在整个生命周期中保持不变,该特性会非常有用。
问题:由于项目PB使用messagelite作为基类,进程测试时使用json作为输入,但messagelite未提供与json互相转换的接口,需要自己实现。
#include "json.hpp"
class Pb2Json
{
public:
using Json = nlohmann::json;
using protobufMsgLite = ::google::protobuf::MessageLite;
public:
static bool Json2MessageLite(const Json& json, Request& messageLite);
static bool MessageLite2Json(const Response& messageLite, Json& json);
}
required关键字:数据发送方和接收方都必须处理这个字段,不然无法通讯
optional关键字:字面意思是可选的意思,protobuf处理的时候加了一个bool的变量,用来标记optional字段是否有值,发送方在发送的时候,这个字段如果有值,就给bool变量标记为true,接收方在收到这个字段的同时,也会收到发送方同时发送的bool变量,拿着bool变量就知道是否有值了。平滑升级就是这个意思。
repeated关键字:重复的意思,protobuf在处理这个关键字的时候,也是optional字段一样,另外加了一个count关键字,标明这个字段有多少个,这样发送方发送的时候,同时发送了count计数和字段起始地址。接收方在收到数据后,按照count来解析对应数据即可。
pb转json
json = Json::parse("{}");
for (int i = 0; i < messageLite.lockids_size(); i++)
{
json["lockIDs"].push_back(messageLite.lockids(i));
}
json转pb,解析json,获取json键值
for(Json::iterator& it = json.begin(); it != json.end(); ++it)
{
//字符串类型的转换
int64_t key = std::atoi(it.key().c_str();
}