Protobuf新手实践:读取.proto文件Descriptor报错求助
解决Protobuf Descriptor功能实践中的解析错误
问题根源
- 解析方式错误:你用
TextFormat::Parse直接解析原始.proto文件,但这个方法仅用于解析FileDescriptorProto的文本序列化格式,不支持Protobuf IDL(.proto)文件的语法,这是导致Expected ":", found "="错误的核心原因。 - 文件路径错误:代码中指定读取
person.pb.h(编译生成的C++头文件),但实际需要处理的是你的person.proto源文件。
解决方法
使用Protobuf官方提供的Importer类动态加载并解析.proto文件,这是获取Descriptor的正确方式,修正后的代码如下:
#include <iostream> #include <google/protobuf/descriptor.h> #include <google/protobuf/compiler/importer.h> int main() { // 替换为你的person.proto文件实际路径 const std::string proto_file_path = "/home/hossein/QtProject/test/person.proto"; // 替换为.proto文件所在目录(用于搜索依赖文件) const std::string proto_dir = "/home/hossein/QtProject/test/"; // 设置.proto文件的搜索路径 google::protobuf::compiler::DiskSourceTree source_tree; source_tree.MapPath("", proto_dir); // 创建Importer实例,负责解析.proto文件 google::protobuf::compiler::Importer importer(&source_tree, nullptr); const google::protobuf::FileDescriptor* file_descriptor = importer.Import(proto_file_path); if (!file_descriptor) { std::cerr << "Failed to import proto file: " << proto_file_path << std::endl; return 1; } // 打印文件定义的消息类型和字段 std::cout << "File " << proto_file_path << " defines the following message types:" << std::endl; for (int i = 0; i < file_descriptor->message_type_count(); i++) { const google::protobuf::Descriptor* message_descriptor = file_descriptor->message_type(i); std::cout << " Message type: " << message_descriptor->full_name() << std::endl; std::cout << " Fields:" << std::endl; for (int j = 0; j < message_descriptor->field_count(); j++) { const google::protobuf::FieldDescriptor* field_descriptor = message_descriptor->field(j); std::cout << " Field name: " << field_descriptor->name() << std::endl; std::cout << " Field type: " << field_descriptor->type_name() << std::endl; } } return 0; }
补充说明
- 编译时需链接Protobuf库,例如g++编译命令:
g++ your_code.cpp -o your_program -lprotobuf - 若你的
.proto文件依赖其他proto文件,只需将依赖文件的目录通过source_tree.MapPath("", dependency_dir)添加到搜索路径中即可。
内容的提问来源于stack exchange,提问作者hossein
相关产品推荐
相关产品推荐

