假设我已经使用以下原始文件编译了一个应用程序(接收器):
syntax = "proto3";
message Control {
bytes version = 1;
uint32 id = 2;
bytes color = 3;
}
,我还有另一个应用程序(发送器),该应用程序最初具有相同的原型文件,但在更新后添加了一个新字段,如:
syntax = "proto3";
message Control {
bytes name = 1;
uint32 id = 2;
bytes color = 3;
uint32 color_id = 4;
}
我已经看到,如果Receiver应用程序尝试解析原型,请更改一些数据,然后将其序列化回去,从而删除来自Transmitter应用程序的添加字段。
我需要一种无需直接解析/序列化原型即可直接访问原始字节的id字段的方法。有可能吗?
这是必需的,因为我在控制消息中有一些“标头”字段,我知道它们永远不会更改,但是由于应用程序更新,可以在同一传输程序应用程序的原型中添加/更改其他字段。
我已经看到:https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.io.coded_stream 但是我无法修改现有的字节流,并且ReadString无法理解字符串的长度。
预先感谢
答案 0 :(得分:1)
我认为没有官方的方法可以做到。您可以按照protobuf(https://developers.google.com/protocol-buffers/docs/encoding#structure)的编码准则手动进行操作。
基本上,您应该这样做:
这很不好,原因有几个。最重要的是,您的代码必须了解有关消息结构和内容(ID的字段号和数据类型)的详细信息,而这正是使用协议缓冲区时要避免的(您始终需要.proto文件中的一些信息) )。
答案 1 :(得分:0)
在proto2语法中,protobuf C ++库用于保留未知字段,以便在您重新编码消息时将保留它们。不幸的是,proto3语法中的have been removed这个功能(与其他功能一样)。
一种解决方法可能是这样:
id
消息中仅设置新的Receiver
值并对其进行编码。这依赖于protobuf功能,即附加消息替换protobuf消息中字段的原始值。
嗯,实际上是在阅读上面链接的问题报告,看来you can turn on unknown field preservation in protobuf version 3.5 and newer。
答案 2 :(得分:0)
只需反序列化整个消息并将其映射到新消息上即可。这是最干净的方法。您没有大量数据,并且可能没有实时要求。创建一个映射器,不要过分考虑问题。