protobuf in C++ with dynamic binding for google::protobuf::M

protobuf in C++ with dynamic binding for google::protobuf::Message

本文关键字:protobuf google for dynamic in C++ with binding      更新时间:2023-10-16

在C++中使用protobuf,我有一系列消息将共享一对编码和解码自定义API,例如Pack((和Unpack((;

但我很快意识到,我必须对消息类型进行硬编码,以便能够将数据从流解码为正确的数据结构。

由于不支持继承,因此我随后查看了Any设施。但是,官方文档太简洁了,无法用工作示例指导我。

我想确认 Any 是否像这样工作:

假设我需要从解码器端的工厂创建一些消息类型,那么......

步骤#1:我必须像这样定义我的proto3

syntax = "proto3";
import "google/protobuf/any.proto";
message Envelope {
google.protobuf.Any actual_msg = 1;
string id = 2;
}
message PublicProfile {
string name = 1;
int32 age = 2;
bool isMale = 3;
}
message PrivateProfile {
string nickname = 1;
int32 money = 2;
}

第 2 步:编码器将像这样工作

//encoder.cpp
Envelope payload;
payload.set_id("my.com/msg/profile.public");
PublicProfile pp;
pp.name = "Tom";
pp.age = 30;
pp.isMale = true;
payload.get_actual_msg().PackFrom(pp); // NOT Sure how to use PackFrom at all!

int pakSize = payload.ByteSize()
std::string packet(pakSize, '');
google::protobuf::io::ArrayOutputStream aos((void*)packet.c_str(), pakSize);
google::protobuf::io::CodedOutputStream* cos = new google::protobuf::io::CodedOutputStream(&aos);
payload.SerializeToCodedStream(cos);

步骤#3:最后解码器需要

// decoder.cpp
Envelope payload;
google::protobuf::io::ArrayInputStream ais(packet.c_str(), packet.size());
google::protobuf::io::CodedInputStream cis(&ais);
payload->ParseFromCodedStream(&cis);
google::protobuf::Any actual_msg = payload.actual_msg();
if (payload.id() == "my.com/msg/profile.public") {
PublicProfile pp;
actual_msg.UnpackTo(&pp);
}

它以这种方式工作吗?

由于没有人愿意回答,我报告我自己的发现。

我们不需要协议中的显式 ID。Any内置了一个ID,由Protobuf自动生成。

解码时,只需调用指定的方法从Any对象中检索 ID,我们就可以自由地将其与任何自定义模式进行匹配

myAnyMsg.type_url()

典型的网址如下所示

type.googleapis.com/<message_type_defined_in_proto>