如何从一组已定义的描述符动态构建新的 protobuf
How to dynamically build a new protobuf from a set of already defined descriptors?
在我的服务器上,我们收到自我描述的消息(定义如此处...顺便说一句,这并不容易,因为在 C++ 中没有任何"好"的例子)。
在这一点上,我从这些自我描述的消息中创建消息没有问题。我可以获取FileDescriptorSet,遍历每个FileDescriptorProto,将每个添加到DescriptorPool中(使用BuildFile,它也给了我每个定义的FileDescriptor)。
从这里,我可以创建在FileDescriptorSet中定义的任何消息,使用DP实例化的DynamicMessageFactory并调用GetPrototype(这很容易做到,因为我们的SelfDescribedMessage需要消息full_name(),因此我们可以调用DP的FindMessageTypeByName方法,为我们提供正确编码的消息原型)。
问题是我如何获取每个已经定义的描述符或消息,并动态构建一个"主"消息,其中包含所有定义的消息作为嵌套消息。这将主要用于保存消息的当前状态。目前,我们只需在服务器中实例化每条消息的类型来处理这个问题(以在不同的程序中保持中心状态)。但是,当我们想要"保存"当前状态时,我们被迫将它们流式传输到此处定义的磁盘。它们一次流式传输一条消息(带有大小前缀)。我们希望有一条消息(一条来统治所有消息),而不是稳定的单独消息流。一旦解决,这可以用于其他事情(基于网络的共享状态,具有优化和轻松的序列化)
由于我们已经有了交叉链接和定义的描述符,人们会认为有一种简单的方法可以从那些已经定义的描述符中构建"新"消息。到目前为止,解决方案已经暗示了我们。我们尝试创建自己的描述符Proto,并从我们已经定义的描述符中添加该类型的新字段,但迷路了(尚未深入研究)。我们还考虑了可能将它们添加为扩展(目前不知道如何这样做)。我们是否需要创建自己的描述符数据库(目前也不知道如何做到这一点)?
有什么见解吗?
位桶上的链接示例源。
希望这个解释会有所帮助。
我正在尝试从一组已定义的消息动态构建消息。已经定义的消息集是通过使用官方 c++ protobuf 教程中解释的"自描述"方法(简要地)创建的(即这些消息不以编译形式提供)。需要在运行时创建此新定义的消息。
尝试对每条消息使用直接描述符,并尝试构建文件描述符Proto。尝试查看数据库描述符方法。两者都没有运气。 目前正在尝试将这些定义的消息作为扩展添加到另一条消息中(即使在编译时,这些定义的消息及其"描述符集"也没有被归类为扩展任何内容),这是示例代码开始的地方。
你需要一个protobuf::DynamicMessageFactory
:
{
using namespace google;
protobuf::DynamicMessageFactory dmf;
protobuf::Message* actual_msg = dmf.GetPrototype(some_desc)->New();
const protobuf::Reflection* refl = actual_msg->GetReflection();
const protobuf::FieldDescriptor* fd = trip_desc->FindFieldByName("someField");
refl->SetString(actual_msg, fd, "whee");
...
cout << actual_msg->DebugString() << endl;
}
我能够通过动态创建一个 .proto 文件并使用导入器加载它来解决这个问题。
唯一的要求是每个客户端要么发送其原型文件(仅在 init 时需要...不是在完全执行期间)。然后,服务器将每个原型文件保存到临时目录。如果可能的话,另一种方法是将服务器指向保存所有需要的原型文件的中央位置。
这是通过首先使用DiskSourceTree将实际路径位置映射到程序中的虚拟路径位置来完成的。然后构建 .proto 文件以导入通过 AND 发送的每个 proto 文件,并在"主消息"中定义一个可选字段。
将master.proto
保存到磁盘后,我使用导入器导入它。现在使用 Importers DescriptorPool 和 DynamicMessageFactory,我能够在一条消息下可靠地生成整个消息。我将在今晚晚些时候或明天举一个例子来说明我所描述的内容。
如果有人对如何使此过程更好或如何做得不同有任何建议,请说出来。
在赏金即将到期之前,我将不回答这个问题,以防其他人有更好的解决方案。
将所有消息序列化为字符串,并使主消息成为(字节)字符串序列怎么样,就像
message MessageSet
{
required FileDescriptorSet proto_files = 1;
repeated bytes serialized_sub_message = 2;
}
- std::向量与传递值的动态数组
- 在c++中用vector填充一个简单的动态数组
- C++中的动态铸造故障
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 内联映射初始化的动态atexit析构函数崩溃
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 使用VerQueryValue检索应用程序的文件描述
- 控制允许动态运行c++的并发操作数
- 如何将这个C++哈希表转换为动态扩展和收缩,而不是使用硬设置的最大值
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 输出没有重复元素的动态数组(收缩数组)C++
- C++为线程工作动态地分割例程
- 正在插入动态数组
- 如何在C/C++中用FD_set Unix设置套接字文件描述符
- 在c++中使用动态分配的问题
- C++中的动态对象与非动态对象
- 如何在动态数组上使用搜索函数
- 如何在动态创建的CMFCToolbar的工具提示中添加描述?
- 如何从一组已定义的描述符动态构建新的 protobuf