正在从协议缓冲区筛选项目
Filtering items from a protocol buffer
我正在开发一款系统控制软件,用于处理硬件设备的控制和状态信息。为了简单起见,我使用一个单一的、适度复杂的协议缓冲区结构来在线程之间进行通信。我在网络接口上也采用了相同的结构,这样外部客户端就可以控制和监控系统的所有部分。
该软件可能使用低比特率数据链路运行,所以我正在寻找减少网络负载的方法。因此,我的问题是:
在不为每个I/O操作解析整个protobuf结构的情况下,有没有一种方法可以过滤(修剪)protobuf以在运行时删除某些消息?
例如,如果我有这个.proto
:
message Status {
optional BusyMsg busy = 10;
optional FaultMsg system_fault = 11;
optional VoltageMsg rail_volts = 3000;
optional InternalStatus internal = 4000;
}
message InternalStatus {
optional PressureMsg head_pressure = 1;
optional TempMgs cabinet_temp = 2;
}
有没有一种简单的方法可以去除(或抑制)rail_volts
或internal
,可能是通过测试大的ID号(在这种情况下是3000和4000)?或者,扩展和属性的良好使用是否会有所帮助?
我知道我可以在I/O边界为所有不想序列化的字段调用Clear()。但我宁愿以某种方式在.proto
中标记它们,而不是依靠网络接口上的C++代码来保持更新。(到目前为止,internal
小节是我最好的主意。我可以删掉它下面的所有内容。)
我并不是在寻求一个彻底的结构解决方案。我想知道我是否错过了API的一个优雅功能。
您可以定义一个简化的状态消息,将完整的状态消息打印为字符串,并将其解析为简化的消息。这意味着您只需要更改proto文件,而不必担心C++API。(这里的复制不是很好。我还不知道如何共享质子。)
// foo.proto
syntax = "proto2";
message Status1 {
optional int64 f1 = 1;
optional int64 f2 = 2;
optional int64 f3 = 3;
}
message Status2 {
optional int64 f1 = 1;
optional int64 f2 = 2;
}
// foo.cc
#include <iostream>
#include "experimental/seanmcl/proto/foo.pb.h"
int main(int argc, char* argv[]){
string str;
{
Status1 s1;
s1.set_f1(5);
s1.set_f2(6);
s1.set_f3(7);
s1.SerializeToString(&str);
}
{
Status2 s2;
s2.ParseFromString(str);
assert(s2.f1() == 5);
assert(s2.f2() == 6);
}
return 0;
}
相对于复制(虽然不是消息的简单性),更好的是:
message Status {
optional StatusRequired status_required = 1;
optional int64 f3 = 3;
}
message StatusRequired {
optional int64 f1 = 1;
optional int64 f2 = 2;
}
{
Status s3;
StatusRequired* s4 = s3.mutable_status_required();
s4->set_f1(5);
s4->set_f2(6);
s3.set_f3(7);
s3.SerializeToString(&str);
}
{
Status s3;
s3.ParseFromString(str);
StatusRequired* s4 (s3.mutable_status_required());
cout << (s4->f1() == 5) << endl;;
cout << (s4->f2() == 6) << endl;;
}
我现在认识到这是你的解决方案,字段的相对重要性被翻转了!
相关文章:
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 无法在 CLion 中构建 C++ 项目
- 运行同一解决方案的另一个项目的项目
- CMake-按正确顺序将项目与C运行时对象文件链接
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 欧拉项目#8答案是大以获得有效答案
- 从链接列表c++中删除一个项目
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- 既然存在危险,为什么项目要使用-I include开关
- cmake在我的项目中所需的所有静态库都不成功
- QT通过C++添加映射QML项目
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- 在linux上调试巨大的C++项目
- 在其他文件中创建类时在 c++ 项目中不起作用
- 使外部项目可用于find_package CMake
- 在子目录中使用target_sources()命令时用于单元测试(qtest)的项目结构
- 如何在Visual Studio中创建C++项目筛选器/文件夹
- 正在从协议缓冲区筛选项目
- 筛选QStandardItemModel或QTreeView中的项目
- 如何从std::映射中筛选项目