之前寫了《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"), "[email protected]");
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": "[email protected]",
"phones": []
}
本文來自部落格園,作者:mkckr0,轉載請注明原文連結:https://www.cnblogs.com/mkckr0/p/15855264.html