如何在C++ Protobuf中反序列化oneof里的重复消息
解决方法
你完全不需要用Descriptor和Reflection,Protobuf生成的代码已经提供了直接访问oneof字段的便捷方法,按以下步骤操作即可:
1. 先修正序列化代码的遗漏
你当前的序列化逻辑里,没把创建好的TestWordTwo对象赋值给sentMessage的payload字段,这会导致序列化出来的数据是空的,反序列化自然拿不到内容。补充这一步:
sentMessage.mutable_test_data()->Swap(data_test); delete data_test; // 记得释放内存,用智能指针(比如std::unique_ptr)会更安全
2. 反序列化后读取数据
反序列化完成后,先判断recvMessage的payload类型,再直接遍历words:
// 判断当前oneof存储的是否是test_data if (recvMessage.payload_case() == TestMessage::kTestData) { // 获取TestWordTwo对象的常量引用 const TestWordTwo& test_data = recvMessage.test_data(); // 逐个遍历words for (int i = 0; i < test_data.words_size(); ++i) { const TestWordOne& word_item = test_data.words(i); uint32_t word_value = word_item.word(); // 这里可以处理拿到的word值,比如打印 std::cout << "第" << i+1 << "个word值:" << word_value << std::endl; } } else { // 处理payload是其他类型的情况 std::cout << "当前payload不是test_data类型" << std::endl; }
补充说明
- Protobuf为oneof字段自动生成了
payload_case()方法,用来判断当前oneof存储的子字段类型,对应的枚举值是TestMessage::kTestData(和你定义的test_data字段对应) - 要修改
test_data的话,用mutable_test_data()获取可修改的指针;只读的话直接用test_data()拿常量引用即可 - 对于
repeated类型的words,Protobuf生成了words_size()获取元素总数,words(i)获取第i个元素的常量引用,序列化时用到的add_words()就是添加元素的方法
内容的提问来源于stack exchange,提问作者Robert M
相关产品推荐
相关产品推荐

