C++中protobuf 动态加载.proto文件
环境:
protobuf: v27.3(2024-08-01)
abseil: 20240722.0
文章目录
- [C++中protobuf 动态加载.proto文件](#C++中protobuf 动态加载.proto文件)
-
- 前言
- [1. 通讯录 addressbook.proto](#1. 通讯录 addressbook.proto)
- [2. C++中测试动态加载.proto文件并输出json](#2. C++中测试动态加载.proto文件并输出json)
- [3. 结果](#3. 结果)
前言
protobuf动态加载.proto文件,可以不生成cpp文件的情况下操作Message对象。
动态加载方式的性能会稍差一些。
1. 通讯录 addressbook.proto
addressbook.proto
syntax = "proto3";
option optimize_for = LITE_RUNTIME; // MessageLite
package com.test;
message Person {
string name = 1;
int32 age = 2;
string phone = 3;
}
message AddressBook {
repeated Person people = 1;
}
2. C++中测试动态加载.proto文件并输出json
main.cpp
#include <iostream>
#include <google/protobuf/compiler/importer.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/util/json_util.h> // MessageToJsonString JsonStringToMessage
int main(int argc, char *argv[])
{
// 1. Setup Importer to dynamically load .proto files
google::protobuf::compiler::DiskSourceTree sourceTree;
sourceTree.MapPath("", ".");
google::protobuf::compiler::MultiFileErrorCollector* errorCollector = nullptr;
google::protobuf::compiler::Importer importer(&sourceTree, errorCollector);
// 2. Import the .proto file
const google::protobuf::FileDescriptor* addressBookFileDescriptor = importer.Import("addressbook.proto");
if (!addressBookFileDescriptor)
{
std::cerr << "Failed to import .proto file." << std::endl;
return -1;
}
// 3. Find the message descriptor
const google::protobuf::Descriptor* addressBookMessageDescriptor = addressBookFileDescriptor->FindMessageTypeByName("AddressBook");
if (!addressBookMessageDescriptor) {
std::cerr << "Message type 'AddressBook' not found in .proto file." << std::endl;
return -1;
}
// 4. Create a dynamic message
google::protobuf::DynamicMessageFactory factory;
const google::protobuf::Message* prototype = factory.GetPrototype(addressBookMessageDescriptor);
google::protobuf::Message* message = prototype->New();
// 5. JSON to PB Message
std::string jsonStr = R"({"people":[{"name":"xiaoming","age":30,"phone":"13012345678"}]})";
google::protobuf::json::JsonStringToMessage(jsonStr, message);
// 6. printf PB JSON
std::string result;
google::protobuf::json::MessageToJsonString(*message, &result);
std::cout << "Dynamic Message From JSON - " << result << std::endl;
// 7. clear
delete message;
getchar();
return 0;
}
CMakeLists.txt
动态加载依赖libprotoc
cmake_minimum_required(VERSION 3.10)
project(main)
# protobuf
add_definitions(-DPROTOBUF_USE_DLLS)
include_directories(include)
link_directories(lib)
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} libprotoc libprotobuf abseil_dll)
目录结构
tree
.
+--- addressbook.proto
+--- CMakeLists.txt
+--- include
+--- lib
+--- main.cpp
3. 结果
Dynamic Message From JSON - {"people":[{"name":"xiaoming","age":30,"phone":"13012345678"}]}