协议缓冲区 - 如何使用 ProtoBuf 扩展在 C++ 中获取多态性

protocol buffers - How to use ProtoBuf extensions to get polymorphism in C++

本文关键字:C++ 获取 多态性 扩展 ProtoBuf 缓冲区 何使用 协议      更新时间:2023-10-16

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

我的原型文件

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;
    }
}

有点类似于这个例子,但我似乎无法通过以下方式设置扩展值

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:"设置":不是"google::p rotobuf::内部::消息类型特征"的成员

不幸的是,这个类似的问题也没有在 c++ 下构造的示例。

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

我遵循了文档中"嵌套扩展"下的示例,该示例仅设置基本类型。我也试图了解rpcz如何解决这个问题,但我失败了,也许一些提示会对这个问题有所帮助?

扩展很像常规字段。对于基元字段,您可以获取访问器来获取和设置字段。但是,对于子消息,您不会获得"set"访问器 - 您可以获得"get"和"mutable",就像常规子消息字段一样。因此,您需要:

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