在 C++ 中更改现有 protobuf 消息的元素

Posted

技术标签:

【中文标题】在 C++ 中更改现有 protobuf 消息的元素【英文标题】:Changing an element of an existing protobuf message in C++ 【发布时间】:2017-02-15 10:53:12 【问题描述】:

我只是想知道,为什么没有人解决我最近遇到的与 google protobufs 相关的问题,但是经过广泛的谷歌搜索、阅读 google 手册页的文档并在 ***-DB 中搜索,我没有找到解决方案。

我在 Ubuntu 14.04.3 LTS 上使用 proto2-c++-API,通过 cmake 文件使用 gcc/g++ 进行编译。

我有一个从文件中读取二进制(序列化)谷歌协议缓冲区消息的应用程序。然后程序的目的是将消息(没有反序列化)发送到另一个应用程序,该应用程序继续处理实际数据。

我现在想修改一些消息,从文件中读取,以便测试第二个应用程序的功能。不幸的是,我的消息包含很多嵌套消息,所以在反序列化后我必须调用类似

message().a().b().c()....x().value(); 

能够处理实际数据。

我现在的问题是,如何在不创建另一个 message 类型的消息的情况下更改 x 的值,我还必须创建所有子消息 (a,b,c...) 并将它们分配给各自的前任,例如在下面的伪代码中?!

a = new a();
b = new b();
c = new c();
...
v = new v();
w = new w();
x = new x();
x.set_value();
w.set_allocated_x_value(x);
v.set_allocated_w_value(w);
...
a.set_allocated_b_value(b);
message.set_allocated_a_value(a);

...
/* forward message to second application */
...


delete x;
delete w;
...
delete a;

显然不可能直接在message-objects 上调用set_value,分别调用它的子对象,如message().a().b().c()....x().set_value();,因为这会违反自动生成的protobuf-messages 的const 要求,它不允许在 const 对象上调用 setter 方法:error: passing xxx as 'this' argument of xxx discards qualifiers

如果有任何创造性的解决方案来避免实现上面发布的递归 new-set_allocated-delete 代码,我将不胜感激。

提前致谢

【问题讨论】:

【参考方案1】:

关键是使用mutable_x() 访问器,因此在您的示例中,您将执行以下操作:

message.mutable_a()->mutable_b()->mutable_c()->set_value(42);

set_allocated_* 方法实际上并不推荐,除非您真的知道自己在做什么,因为它们可以让您对通常不需要的内存管理进行特殊控制,除非您专门尝试优化特定部分代码。

【讨论】:

以上是关于在 C++ 中更改现有 protobuf 消息的元素的主要内容,如果未能解决你的问题,请参考以下文章

在 Java 中读取 protobuf 消息时出现异常

Protobuf-Net 似乎重用现有对象而不是创建和分配新对象

用于非 protobuf 类的 protobuf `oneof` 功能的 C++ 实现

带有谷歌时间戳的 Protobuf C++ 消息导致段错误 [重复]

在 Java 和 C++ 应用程序中使用 protobuf 解析时出错

Protobuf ParseDelimitedFrom C++ 中的实现