Protobuf 动态加载 .pb 文件并操作 Message

之前写了《Protobuf 动态加载 .proto 文件并操作 Message》。除了直接读取 .proto 文件之外,还有一种类似的方法。先把 .proto 文件编译成 .pb 文件,再读取 .pb 文件。这种方法虽然比直接读取 .proto 多了一步,但是在运行期加载更快。
仍然使用之前的的 .proto 文件作为示例。使用 protoc 将 .proto 文件编译为 .pb 文件。

./3rdparty/bin/protoc -I./proto -oaddressbook.pb --include_imports ./proto/addressbook.proto

注意,这里有两个 .proto 文件,应该选择没有被依赖的的 .proto 文件作为参数,并且添加 --include_imports 选项。这样,所有 .proto 文件及其依赖的 .proto 文件都被编进同一个 .pb 文件。

#include <iostream> #include <fstream> #include <google/protobuf/dynamic_message.h> #include <google/protobuf/util/json_util.h> #include <google/protobuf/descriptor.pb.h> using namespace google::protobuf; int main() { std::ifstream pb_file("./addressbook.pb", std::ios::binary); if (!pb_file.is_open()) { return -1; } FileDescriptorSet file_descriptor_set; if (!file_descriptor_set.ParseFromIstream(&pb_file)) { return -1; } DescriptorPool pool; for (int i = 0; i < file_descriptor_set.file_size(); ++i) { pool.BuildFile(file_descriptor_set.file(i)); } const Descriptor* person_descriptor = pool.FindMessageTypeByName("tutorial.Person"); DynamicMessageFactory message_factory; const Message* default_person = message_factory.GetPrototype(person_descriptor); Message* person = default_person->New(); const Reflection* reflection = person->GetReflection(); reflection->SetString(person, person_descriptor->FindFieldByName("name"), "abc"); reflection->SetInt32(person, person_descriptor->FindFieldByName("id"), 123456); reflection->SetString(person, person_descriptor->FindFieldByName("email"), "abc@163.com"); util::JsonPrintOptions json_options; json_options.add_whitespace = true; json_options.always_print_primitive_fields = true; json_options.preserve_proto_field_names = true; std::string output; util::MessageToJsonString(*person, &output, json_options); std::cout << "====== Person data ======" << std::endl; std::cout << output; delete person; }

输出

====== Person data ====== { "name": "abc", "id": 123456, "email": "abc@163.com", "phones": [] }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgzsxw.html