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
#include
#include
#include
#include
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"), );
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": ,
"email": "abc@163.com",
"phones": []
}
新闻名称:Protobuf 动态加载 .pb 文件并操作 Message
浏览路径:http://abwzjs.com/article/dsogoeg.html