簡體   English   中英

C++ 中的 protobuf 與 google::protobuf::Message 的動態綁定

[英]protobuf in C++ with dynamic binding for google::protobuf::Message

在 C++ 中使用 protobuf,我有一系列消息將共享一對編碼和解碼自定義 API,例如 Pack() 和 Unpack();

但我很快意識到我必須對消息類型進行硬編碼,才能將來自 stream 的數據解碼為正確的數據結構。

由於不支持 inheritance,因此我查看了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);
}

它是這樣工作的嗎?

由於沒有人願意回答,我正在報告我自己的發現。

我們不需要協議中的顯式 ID。 Any有一個內置的 ID,由 Protobuf 自動生成。

解碼時,只需調用指定方法從Any object 中檢索 ID,我們可以自由地將其與任何自定義模式匹配

myAnyMsg.type_url()

一個典型的 URL 看起來像這樣

type.googleapis.com/<message_type_defined_in_proto>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM