【问题标题】:How to use ProtoBuf extensions to get polymorphism in C++如何使用 ProtoBuf 扩展在 C++ 中获得多态性
【发布时间】:2015-06-15 16:49:40
【问题描述】:

我正在尝试定义一个通用的基本消息,它定义了消息的类型(以便于解析),然后用实际的消息进行扩展。消息将以 RPC 方式使用。

我的 .proto 文件

syntax = "proto2";
package userapi;

// wrapper for commands
message Command
{
    // for "subclassing"
    extensions 100 to max;

    enum Type
    {
        Request = 1;
        Response = 2;
    }

    required Type type = 1;
}   

message Request
{
    // register this message type as extension to command
    extend Command
    {       
        optional Request command = 100;
    }

    optional string guid = 1;
}

message Response
{
    // register this message type as extension to command
    extend Command
    {       
        optional Response command = 101;
    }

    optional string guid = 1;

    //! error handling for command
    optional ErrorMsg error = 2;

    message ErrorMsg
    {
        enum ErrorCode
        {
            //! no error occured
            NONE = 0;
            //! the requested GUID already existed
            GUID_NOT_UNIQUE = 1;
        }

        optional string ErrorString = 1;
    }
}

有点类似于this example,但我似乎无法通过设置扩展值

Command commandRequest;
commandRequest.set_type(Command_Type_Request);

auto extension = commandRequest.GetExtension(Request::command);
extension.set_guid("myGuid");

commandRequest.SetExtension(Request::command, extension);

SetExtension() 调用失败并显示以下错误消息

错误 C2039:“Set”:不是“google::protobuf::internal::MessageTypeTraits”的成员

不幸的是,这个similar question 也没有在 c++ 下构建的示例。

我是否误解了扩展的概念?有什么更干净的方法来建立这个(不,我不想将命令序列化为字符串)。

我正在关注documentation 中“嵌套扩展”下的示例,它只设置基本类型。我也尝试了解rpcz是如何解决这个问题的,但是我失败了,也许一些提示会帮助解决这个问题?

【问题讨论】:

  • 顺便说一句,扩展不是 proto3 的一部分 - 因此,如果您希望将来将消息迁移到 proto3,您可能需要重新考虑使用扩展。
  • 好的,谢谢,我也开放了 proto3 解决方案!我想定义很多可选字段将是一个? :/ 类似于this
  • 您可能想查看Any 类型,或者可能是oneof。这里有很多不同的选项,具体取决于您的具体要求。

标签: c++ protocol-buffers zeromq


【解决方案1】:

扩展很像常规字段。对于原始字段,您可以使用访问器来获取和设置该字段。但是,对于子消息,您不会获得“set”访问器——您会获得“get”和“mutable”,就像您获得常规子消息字段一样。所以,你想要:

Request* request =
    commandRequest.MutableExtension(Request::command);
request->set_guid("myGuid");

【讨论】:

  • 使用 MutableExtension() 的第二个参数,代码无法编译,这是预期的和需要的吗?
  • @x29a 这是一个复制粘贴错误。您的编辑是正确的。可悲的是,版主似乎拒绝了您的编辑。我直接更新了帖子。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-12
  • 1970-01-01
  • 1970-01-01
  • 2015-03-17
  • 1970-01-01
  • 1970-01-01
  • 2022-06-30
相关资源
最近更新 更多