最近用到加载配置文件为 protobuf 的功能,因为多配置,需要使用protobuf.any功能。
问题:写好json后,json 中的内容对应 protobuf.any 的部分无法正常解析
网上搜索许久,最后还是鼓哥给力,一下找到了结果。
解决方法:
protobuf.any
的实现原理为封装的protobuf.message转换的串
+此message的类型(即type)
。
因此,官方的方案很直接,在对应protobuf.any部分的json串,添加一个json项@type
,内容为type.googleapis.dev/module.class.name
。
示例代码:
test.proto 文件:
package module;
import "google/protobuf/any.proto";
message A {
int32 val = 1;
}
message B {
string text = 1;
google.protobuf.Any data = 2;
}
实现代码:
#include <iostream>
#include <string>
#include <google/protobuf/util/json_util.h>
#include "test.pb.h"
int main(){
module::A a;
a.set_val(3);
module::B b;
*b.mutable_text() = std::string("abc");
b.mutable_data()->PackFrom(a);
std::string json;
std::cout<<"input:"<<std::endl;
auto status = google::protobuf::util::MessageToJsonString(b, &json);
std::cout << json << std::endl;
std::cout<<"output:"<<std::endl;
module::A a2;
module::B b2;
google::protobuf::util::JsonStringToMessage(json, &b2);
std::cout << "B.text: " << b2.text() << std::endl;
if (b2.data().Is<cargo::prediction::proto::TestA>()) {
if (b2.data().UnpackTo(&a2))
std::cout << "A.val: " << a2.val() << std::endl;
}
return 0;
}
输出:
input :
{“text”:“abc”,“data”:{"@type":“type.googleapis.com/module.A”,“val”:3}}
output :
B.text: abc
A.val: 3
另,对于很常见的类型,比如时长
,写json时,也需要写成json.object
并添加@type
。如
{
@type:"type.googleapis.com/google.protobuf.Duration",
"value":"1.2s"
}