【问题标题】:protocol buffers cpp embedded message协议缓冲区 cpp 嵌入消息
【发布时间】:2013-12-05 08:36:56
【问题描述】:

我的 .proto 文件看起来像

message Cmd
{
      int code =  1;
}

message CmdOne
{
      required Cmd cmd = 1;
      required int data = 2;
}

message CmdTwo
{
      required Cmd cmd = 1;
      required string data = 2;
}

在我的 cpp 文件中,我想声明 CmdOneCmdTwo 的对象并设置 cmddata 成员。但是生成的pb.h文件没有CmdOneCmdTwo对象的cmd成员的set方法,但是data成员有set的方法。如何为每个对象设置cmd 的值?

我不想在 CmdOneCmdTwo 消息中定义消息 Cmd。我想重用 Cmd 消息,因为我有 10 条消息 CmdOneCmdTen

【问题讨论】:

    标签: c++ protocol-buffers


    【解决方案1】:

    您有几个不同的选择。您可以获得指向cmd 字段的非常量指针,然后适当地分配值:

    CmdOne cmd_one;
    Cmd* cmd(cmd_one.mutable_cmd());
    cmd->set_code(2);
    // Previous 2 lines could be simplified to:
    // cmd_one.mutable_cmd()->set_code(2);
    

    或者,如果你想将Cmd 的构造实例传递给CmdOne,你可以这样做:

    Cmd* cmd(new Cmd);
    cmd->set_code(1);
    
    CmdOne cmd_one;
    cmd_one.set_allocated_cmd(cmd);  // Takes ownership of cmd -
                                     // you don't call 'delete cmd'
    

    来自the docs 的“单一嵌入式消息字段”部分:

    给定消息类型:

    message Bar {}
    

    对于这些字段定义中的任何一个:

    optional Bar foo = 1;
    required Bar foo = 1;
    

    编译器会生成以下访问器方法:

    ...

    Bar* mutable_foo()
    

    返回一个可变指针,指向存储字段值的Bar 对象。如果在调用之前未设置该字段,则返回的Bar 将不会设置任何字段(即它将与新分配的Bar 相同)。调用此函数后,has_foo() 将返回 truefoo() 将返回对同一 Bar 实例的引用。指针因调用Clear()clear_foo() 而失效。

    ...

    void set_allocated_foo(Bar* bar)
    

    Bar 对象设置为字段并释放前一个字段值(如果存在)。如果Bar 指针不是NULL,则消息获得分配的Bar 对象的所有权,has_foo() 将返回true。否则,如果BarNULL,则行为与调用clear_foo() 相同。

    【讨论】:

    • 如何从我的 C++ 代码中创建像 OP 一样的消息文件。我有一个输入 xml 文件,我使用 C++ 程序解析并填充了数据结构。有没有办法从我的 C++ 代码自动创建一个消息文件?谢谢
    【解决方案2】:
    Cmd my_command;
    
    theCommand.set_code(5);
    
    CmdOne cmd_one;
    
    cmd_one.mutable_cmd().copyFrom(my_command);
    

    【讨论】:

    • mutable_[something].copyFrom(other_something) 实际上复制了给定的数据。如果你对两个父对象使用 set_allocated_[something]() ,那么当一个父对象死亡时,它会破坏子对象后面的内存,然后当另一个父对象死亡时,它会尝试破坏同一个子对象后面的内存,但它已经被破坏了。这会导致分段错误。所以 copyFrom() 非常适合我。
    【解决方案3】:

    我认为最简单的方法是这样的:

    Cmd cmd;
    cmd.set_code(1);
    CmdOne cmd_one;
    *(cmd_one.mutable_cmd()) = cmd;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多