修改原始protobuf流
modify raw protobuf stream
假设我使用以下原型文件编译了一个应用程序(Receiver(:
syntax = "proto3";
message Control {
bytes version = 1;
uint32 id = 2;
bytes color = 3;
}
我有另一个应用程序(Transmitter(,它最初有相同的原型文件,但在更新后添加了一个新字段,如:
syntax = "proto3";
message Control {
bytes name = 1;
uint32 id = 2;
bytes color = 3;
uint32 color_id = 4;
}
我已经看到,如果Receiver应用程序试图解析proto,更改一些数据,然后将其串行化,则来自Transmitter应用程序的添加字段将被删除。
我需要一种方法来更改直接访问原始字节的id字段,而不必解析/序列化proto。有可能吗?
这是必要的,因为我在控制消息中有一些"标题"字段,我知道这些字段永远不会更改,但由于应用程序更新,其他字段可以在transmitter应用程序的同一原型中添加/更改。
我看到了:https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.io.coded_stream但我无法修改现有的字节流,ReadString也无法理解字符串长度。
提前感谢
我不认为有官方的方法可以做到这一点(https://developers.google.com/protocol-buffers/docs/encoding#structure)。
基本上你应该这样做:
- 从第一位开始解码
- 解码,直到达到id的字段号
- 识别表示id的位,并将其替换为新的(编码的!(id
这很糟糕,有几个原因。最重要的是,您的代码必须了解有关消息结构和内容的详细信息(id的字段号和数据类型(,而这正是您在使用协议缓冲区时想要避免的(您总是需要.proto文件中的一些信息(。
在proto2语法中,protobuf C++库用于保留未知字段,以便在重新编码消息时保留这些字段。不幸的是,这个特性(和其他许多特性一样(已经在proto3语法中删除了。
一种变通方法是这样做:
- 仅在
Receiver
消息中设置新的id
值并对其进行编码 - 将此数据附加到原始二进制数据之后
这依赖于protobuf功能,即附加的消息替换protobuf消息中字段的原始值。
嗯,实际上阅读了上面链接的问题报告,似乎你可以在protobuf 3.5及更新版本中打开未知字段保存。
只需反序列化整个消息并将其映射到新消息上。这是最干净的方式。您没有太多的数据,可能也没有实时性要求。创建一个映射器,不要过度思考问题。
- 将浮动的heightmap数组导出为16位原始值
- 给定一个向量,如何找到该向量的所有子集和的原始索引
- 有没有办法从非C/C++文件中读取C++原始字符串文字的内容
- 带有Protobuf序列化的C++Hazelcast:字符串不是UTF-8格式的
- 是否可以将llvm::FunctionType转换为C/C++原始函数指针
- Google protobuf 时间戳未声明标识符,在 Windows 上具有C++
- 如何将原始字节附加到 std::vector?
- 从堆栈分配的原始指针构造智能指针
- 如何重写全局方法名称以在调用原始方法之前将我的代码推到前面
- 将unique_ptr分配给原始指针
- 如何继承 Protobuf 生成的C++类
- 是否可以从 OpenGL 缓冲区获取原始大小的像素?
- 使用 OpenSSL 从内存中读取原始 SSL/TLS 证书
- 如何将唯一指针的 std::vector 转换为原始指针的 std::span?
- 从原始字节解码协议缓冲区(以 C++为单位)
- C ++如何在原始抽象类中创建一个函数,该函数接受派生类的输入
- C++:尝试使用等效的 STL 算法消除原始循环
- 如何在连接器 C++ 中将原始字节转换为字符串
- 通过引用传递类不会更改原始类
- 修改原始protobuf流