在协议缓冲区中定义字典

Posted

技术标签:

【中文标题】在协议缓冲区中定义字典【英文标题】:Define dictionary in protocol buffer 【发布时间】:2012-07-13 16:20:45 【问题描述】:

我对协议缓冲区和 C++ 都很陌生,所以这可能是一个基本问题,但我没有任何运气找到答案。基本上,我想要在我的.proto 文件中定义的字典的功能,例如enum。我正在使用协议缓冲区发送数据,并且我想定义单位及其各自的名称。 enum 可以让我定义单位,但我不知道如何将人类可读的字符串映射到那个。

作为一个例子,.proto 文件可能类似于:

message DataPack 
    // obviously not valid, but something like this
    dict UnitType 
        KmPerHour = "km/h";
        MiPerHour = "mph";
    

    required int id = 1;
    repeated DataPoint pt = 2;

    message DataPoint 
        required int id = 1;
        required int value = 2;
        optional UnitType theunit = 3;
    

然后有类似创建/处理消息的东西:

// construct
DataPack pack;
pack->set_id(123);
DataPack::DataPoint pt = pack.add_point();
pt->set_id(456);
pt->set_value(789);
pt->set_unit(DataPack::UnitType::KmPerHour);

// read values
DataPack::UnitType theunit = pt.unit();
cout << theunit.name << endl; // print "km/h"

我可以用单元名称定义一个enum 并编写一个函数将它们映射到接收端的字符串,但是将它们定义在同一个位置会更有意义,而且该解决方案似乎太复杂了(至少,对于最近被 Python 的便利性宠坏的人来说)。有没有更简单的方法来做到这一点?

【问题讨论】:

1st:这个问题与C++无关,你应该去掉这个标签。第二:我认为这超出了 protobuf 的主要目的,即为数据提供有效的有线格式。我会选择 enum 可读字符串映射解决方案。虽然最好使用 protobuf 插件来生成必要的映射代码,例如使用特殊的注释标签。 【参考方案1】:

您可以使用自定义选项将字符串与每个枚举成员关联: https://developers.google.com/protocol-buffers/docs/proto#options

它在 .proto 中看起来像这样:

extend google.protobuf.FieldOptions 
  optional string name = 12345;


enum UnitType 
    KmPerHour = 1 [(name) = "km/h"];
    MiPerHour = 2 [(name) = "mph"];

但请注意,一些第三方 protobuf 库不理解这些选项。

【讨论】:

这看起来正是我想要的,尽管我认为我需要使用EnumValueOptions 而不是FieldOptions。谢谢。不过,我在使用 C++ 访问结果时遇到问题 - 您能否举一个实际检索值的简短示例? 仅供参考,我发布了一个问题,询问读取值 here 的示例并找到了一个可行的解决方案。再次感谢您为我指明正确的方向! 你为什么 protobuf3 团队忽略了保留字符串或 int 常量的能力?这是使用 .proto 文件开始时最基本和最明显的特性——拥有一个用于跨平台消息模式的源文件。啊!【参考方案2】:

在 proto3 中是:

extend google.protobuf.EnumValueOptions 
  string name = 12345;


enum UnitType 
  KM_PER_HOUR = 0 [(name) = "km/h"];
  MI_PER_HOUR = 1 [(name) = "mph"];

并在 Java 中访问它:

UnitType.KM_PER_HOUR.getValueDescriptor().getOptions().getExtension(MyOuterClass.name);

【讨论】:

以上是关于在协议缓冲区中定义字典的主要内容,如果未能解决你的问题,请参考以下文章

您如何管理协议缓冲区定义文件?

在协议缓冲区中注释推送 rpc 调用

如何通过套接字发送.proto(协议缓冲区)中定义的类

在 ZeroMQ 中使用协议缓冲区实现 RPC

从 Google 协议缓冲区中的重复字符串(列表)中删除一个随机值

协议缓冲区(Protocol Buffers)