如何从一组已定义的描述符动态构建新的protobuf?

g19*_*tic 28 c++ dynamic protocol-buffers

在我的服务器上,我们收到了自我描述的消息(这里定义 ......因为在c ++中没有任何'好'的例子),这并不是那么简单.

在这一点上,我没有问题从这些自我描述的消息中创建消息.我可以使用FileDescriptorSet,遍历每个FileDescriptorProto,将每个文件添加到DescriptorPool(使用BuildFile,它也为我提供了每个定义的FileDescriptor).

从这里我可以创建在FileDescriptorSet中定义的任何消息,其中DynamicMessageFactory与DP一起实例化并调用GetPrototype(这很容易,因为我们的SelfDescribedMessage需要消息full_name(),因此我们可以调用FindMessageTypeByName方法DP,给我们正确编码的Message Prototype).

问题是如何获取每个已定义的描述符或消息,并动态构建包含所有已定义消息的"主"消息作为嵌套消息.这主要用于保存消息的当前状态.目前我们只是通过实例化服务器中每种消息的类型来处理这个问题(以保持不同程序的中心状态).但是当我们想要"保存"当前状态时,我们不得不按照此处的定义将它们流式传输到磁盘.它们一次流式传输一条消息(带有大小前缀).我们希望有一条消息(一条用于统治所有消息)而不是单独消息的稳定流.一旦解决了这个问题,它就可以用于其他事情(基于网络的共享状态,优化和简单的序列化)

由于我们已经有了交叉链接和定义的描述符,人们会认为有一种简单的方法可以从那些已定义的消息构建"新"消息.到目前为止,解决方案已经提到了我们.我们已经尝试创建我们自己的DescriptorProto并从已经定义的描述符中添加该类型的新字段但是迷路了(还没有深入研究这个).我们还看过可能会将它们添加为扩展名(目前未知如何).我们是否需要创建自己的DescriptorDatabase(此时还不知道如何操作)?

任何见解?


BitBucket上的链接示例源.


希望这个解释会有所帮助.

我试图从一组已定义的消息动态构建一个消息.已经定义的消息集是使用官方c ++ protobuf教程中(简要说明)解释的"自描述"方法创建的(即这些消息在编译形式中不可用).需要在运行时创建此新定义的消息.

尝试使用每个消息的直接描述符并尝试构建FileDescriptorProto.试过看过DatabaseDescriptor方法.两个都没有运气.目前正试图将这些定义的消息添加为另一条消息的扩展(即使在编译时那些定义的消息,并且它们的'描述符集'也没有被分类为扩展任何内容),这是示例代码开始的地方.

小智 6

你需要一个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;
}
Run Code Online (Sandbox Code Playgroud)


g19*_*tic 5

我能够通过动态创建一个 .proto 文件并使用Importer加载它来解决这个问题。

唯一的要求是每个客户端要么通过其 proto 文件发送(仅在初始化时需要......而不是在完全执行期间)。然后服务器将每个 proto 文件保存到一个临时目录。如果可能,另一种方法是将服务器指向一个包含所有所需 proto 文件的中心位置。

这是通过首先使用 DiskSourceTree 将实际路径位置映射到程序虚拟位置来完成的。然后构建 .proto 文件以导入发送的每个 proto 文件,并在“主消息”中定义一个可选字段。

master.proto一直保存到磁盘,我与进口商导入。现在使用 Importers DescriptorPool 和 DynamicMessageFactory,我能够在一条消息下可靠地生成整个消息。我将在今晚或明天晚些时候举一个我正在描述的例子。

如果有人对如何改进此过程或如何使其与众不同有任何建议,请说出来。

我将不回答这个问题,直到赏金即将到期,以防其他人有更好的解决方案。

  • 你有你如何实施这个的例子吗? (5认同)