当前位置: 首页 > 知识库问答 >
问题:

如何在. proto文件中处理带有协议缓冲区的通用类型Object?

赫连智
2023-03-14

我花了一些时间寻找一些替代方法来处理通用对象,我见过类似于我的问题,但没有我想的那么具体?协议缓冲区有多种标量类型,我可以使用,但是它们大多是原始的。我希望我的消息是灵活的,并且能够有一个字段,它是某种列表。

假设我的. proto文件看起来像这样:

   message SomeMessage
   {
      string datetime = 1;
      message inputData // This would be a list
      {
         repeated Object object = 1;
      }
      message Object 
      {
          ? // this need to be of a generic type - This is my question
          // My work around - Using extentions with some Object
          //List all primitive scalar types as optional and create an extension 100 to    max;
      }
      message someObject //some random entity - for example, employee/company etc.
      {  
          optional string name = 1; optional int32 id = 2;
      }
      extend Object 
      {
          optional someObject obj = 101;
      }
  } 

这样就可以了,可以工作了,我有一个列表,对象可以是任何原始类型,也可以是列表

如果协议缓冲区无法处理通用对象类型,是否还有其他替代方案可以处理?非常感谢在这件事上给予的任何帮助。

共有3个答案

李昊苍
2023-03-14

实现通用消息功能是可能的,但是仍然添加新类型需要重建原始类。

使用包装器类

message Wrapper {
    extensions 1000 to max;
    required uint32 type = 1;
}

然后添加一些类型

message Foo {
    extend Wrapper {
        optional Foo item = 1000;
    }

    optional int attr1_of_foo = 1;
    optional int attr2_of_foo = 2;
    optional int attr3_of_foo = 3;
}

message Bar {
    extend Wrapper {
        optional Bar item = 1001;
    }

    optional int attr1_of_bar = 1;
    optional int attr2_of_bar = 2;
    optional int attr3_of_bar = 3;
}

看看我们如何在我们希望由包装类使用扩展存储的类中扩展包装类。

现在,创建Foo包装对象的示例。我使用Python,因为它是最精简的形式。其他语言也可以这样做。

wrapper = Wrapper()
wrapper.type = Foo.ITEM_FIELD_NUMBER
foo = wrapper.Extensions[Foo.item]
foo.attr1_of_foo = 1
foo.attr2_of_foo = 2
foo.attr3_of_foo = 3
data = wrapper.SerializeToString()

以及反序列化的例子

wrapper = Wrapper()
wrapper.ParseFromString(data)
if wrapper.type == Foo.ITEM_FIELD_NUMBER:
    foo = wrapper.Extensions[Foo.item]
elif wrapper.type == Bar.ITEM_FIELD_NUMBER:
    bar = wrapper.Extensions[Bar.item]
else:
    raise Exception('Unrecognized wrapped type: %s' % wrapper.type)

现在,因为您想要通用集合,所以让Wrapper成为其他消息的重复字段,瞧。

当然,这不是一个完整的解决方案,这个架构需要更多的打包,以便于使用。有关Protobuf扩展的更多信息,请阅读,尤其是嵌套扩展(https://developers.google.com/protocol-buffers/docs/proto#nested)或者谷歌关于项目编组。

吉凯捷
2023-03-14

虽然我迟到了,只是为了吸引新的读者,你可以用字节来代替对象,也可以是任何可以序列化/反序列化的对象。

仇建茗
2023-03-14

如Marc Gravell所述-协议缓冲区不处理泛型或继承。

 类似资料:
  • 问题内容: 我正在尝试动态解析Java中的给定.proto文件,以解码Protobuf编码的二进制文件。 我有以下解析方法,其中“ proto”字符串包含.proto文件的内容: 但是,执行时,先前的方法将引发消息“协议消息标签的电线类型无效”的异常。我使用了来自Google的示例.proto文件,因此我认为它是有效的:https : //github.com/google/protobuf/bl

  • 我目前在我的protoc.exe.旁边有一个名为addressbook.proto的文件,我在生成. h和. cc文件时遇到了困难 然而,我得到以下回应 关于我可能做错了什么有什么建议吗?

  • 我正在使用模拟开放框架架构SOFA(语言),我的目标是在一些沙发源本机数据与其他外部应用程序之间设置一些通信类型。按照这个顺序,我使用ZeroMQ将沙发数据传输到python外部应用程序。 在SOFA( 文件,以下字段:,,? 目前,文档中不清楚如何定义与向量和其他数据类型相关的字段,如SOFA原生的(四元数)。 Vec3d和Quat由以下元素组成: 是否可以定义为枚举数? 更新 目前,我的暂定仪

  • 我是协议缓冲区的新手,我想知道是否可以搜索协议缓冲区二进制文件并以结构化格式读取数据。例如,如果我的.proto文件中的一条消息有4个字段,我希望序列化该消息,并将多条消息写入一个文件,然后在该文件中搜索特定的字段。如果我找到该字段,我希望以与写入时相同的结构化格式读回消息。对于协议缓冲区,这是可能的吗?如果可能,任何示例代码或示例都将非常有用。谢谢

  • 是否有可能解析传入的google协议缓冲区数据报而不使用任何缓冲区。原始文件?我只是现在使用协议缓冲区对其进行了序列化,但不知道IDL文件。 我在寻找一种通过某种反射来迭代任何值的方法?这可能吗? 非常感谢。

  • (见底部更新) Tilemaker是一个OpenStreetMap程序,用于从OSM pbf数据文件生成Mapbox矢量图块(其本身就是协议缓冲区(pbf)文件)。我已经编译了它,并用它创建了一个矢量平铺目录。我无法用Python解析这些文件。 我使用以下内容创建了矢量平铺: 然后,我以Google的Protocol Buffers python教程为基础,以这种方式创建了一个简单的python程