Работая с protobuf в C ++, у меня есть серия сообщений, которые будут совместно использовать одну пару пользовательских 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, '\0');
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);
}
Работает ли он таким образом?