C++中protobuf 动态加载.proto文件

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"}]}
相关推荐
t-think19 小时前
C++ string 类(上)—— string类初识与常用接口详解
开发语言·c++
cpp_learners19 小时前
C++ 实现责任链模式(Chain of Responsibility):从一堆 if-else 到可插拔的处理管道
开发语言·c++·责任链模式
郝学胜_神的一滴20 小时前
C++11 工程级应用 12:编译期类型魔法,干掉重复与臃肿的代码
c++·visual studio
David猪大卫21 小时前
【C++修炼】哈希表的实现
数据结构·c++·笔记·学习·算法·哈希算法·散列表
广州山泉婚姻21 小时前
列表初始化:C++11全新初始化体系
c++·人工智能
莫生灬灬21 小时前
灵码 LingBuilder:用中文写代码,确定性生成真实 C++ 工程(开源)
c++·开源·mfc
浅念-21 小时前
C++ Protobuf 入门实战:基于通讯录项目吃透proto3语法与序列化
linux·服务器·网络·c++·protobuf·proto·proto3
汉克老师1 天前
CSP-J 初赛(以满分为目标):第三十九课《数学与逻辑②——阶乘、排列数与组合数:公式到底从哪里来?》
c++·csp-j·小学生·学c++编程
水饺编程1 天前
第5章,[Win32 章节] :在平面直角坐标系中描点
c语言·c++·windows·visual studio
linx2951 天前
单元九 · 零基础路线图-第 7–9 周·类与 RAII
c语言·开发语言·数据结构·c++·嵌入式硬件·算法