pb生成文件和反射
1.protoc生成文件
指定生成的目录和proto文件路径,
protoc --cpp_out=./ ./echo.proto
// echo.proto
syntax = "proto3";package echo;option cc_generic_services = true;message EchoRequest {string msg = 1;
}message EchoResponse {string msg = 2;
}service EchoService {rpc Echo(EchoRequest) returns (EchoResponse);
}
使用 protoc 命令编译 .proto 文件时,会生成两个主要的 C++ 文件:
echo.pb.h(头文件)echo.pb.cc(源文件)
1.1 pb头文件
echo.pb.h 是 Protocol Buffers 自动生成的头文件,主要用于声明消息(message类型)的类、方法、枚举以及相关的类型信息,还有服务类(Service类)。它的内容包含以下几个部分:
-
类声明:为每个
.proto文件中的消息定义一个对应的 C++ 类。例如,如果你在.proto文件中定义了一个Message类型,头文件中会生成一个Message类。 -
字段的访问器和修改器方法:每个消息类中的字段都会有 getter 和 setter 函数。这些函数用于访问和修改 Protocol Buffers 消息中的字段。例如,
set_field()、field()、clear_field()等函数。 -
// 序列化和反序列化函数:包含用于将消息对象序列化为二进制格式或从二进制格式反序列化的函数。常见的方法包括
SerializeToString()和ParseFromString()。// 这个实际不在生成的文件中。 -
其他辅助函数:如比较函数(
operator==),清理函数(Clear()),以及元数据函数(例如descriptor())。
服务类类型:
服务类 EchoService 是一个抽象类,声明了服务器端和客户端接口,具体如下:
服务端接口:EchoService::Echo()是一个虚函数,必须在服务器端的实现类中进行具体的定义。服务器端代码需要继承这个类并实现其中的Echo()方法。
class EchoService : public ::grpc::Service {public:virtual ~EchoService();// Abstract method to be implemented on the server sidevirtual ::grpc::Status Echo(::grpc::ServerContext* context,const EchoRequest* request,EchoResponse* response) = 0;// Method to register the service with a gRPC server::grpc::ServerUnaryCallHandlerFactoryBase<EchoRequest, EchoResponse>* RegisterEcho();// Other methods for service registration and reflection
};
服务器端实现:服务器端需要继承 EchoService 类并实现 Echo() 方法。例如:
class MyEchoServiceImpl : public EchoService {::grpc::Status Echo(::grpc::ServerContext* context, const EchoRequest* request, EchoResponse* response) override {// Implement your logic hereresponse->set_msg("Response to: " + request->msg());return ::grpc::Status::OK;}
};
- 客户端接口:
Stub是客户端调用远程RPC服务的接口,声明如下。客户端代码通过Stub调用Echo()方法进行远程调用,发送请求并接收响应。
class EchoService::Stub : public ::grpc::Client {public:// Method to invoke the RPC from the client::grpc::Status Echo(::grpc::ClientContext* context, const EchoRequest& request, EchoResponse* response);
};
1.2 pb源文件
echo.pb.cc 是 Protocol Buffers 自动生成的源文件,主要包含消息类方法的实现。它是 echo.pb.h 中声明的方法的具体定义。源文件的内容主要包括:
-
构造函数和析构函数:消息类的构造函数、析构函数,以及复制构造函数等。
-
字段访问器和修改器的实现:具体实现
pb.h文件中声明的 getter 和 setter 函数,用于访问和修改pb 消息中的字段。 -
序列化和反序列化的实现:具体实现序列化和反序列化的方法,例如
SerializeToArray()、ParseFromArray()等。 -
字段的内存管理:管理动态分配的内存(如果消息包含嵌套消息或
repeated字段)。 -
消息的元数据:通常包含与消息相关的反射信息,用于支持 Protocol Buffers 的动态功能(如反射系统,
descriptor元数据等)。
2.pb反射机制
Protocol Buffers 的反射机制允许你在运行时动态地操作消息对象,而无需在编译时明确知道其类型或字段。// 可以认为能获取到元数据的机制就是反射机制。
反射使得开发者可以在运行时通过一种通用的方式来操纵 Protocol Buffers 消息,包括:
- 获取消息的元数据(如字段的名称、类型等)。
- 动态访问和修改消息的字段,即使这些字段在编译时是未知的。
- 遍历所有的字段,包括已设置的和未设置的字段。
- 动态序列化和反序列化消息,无需依赖具体的消息类型。
反射机制特别适合以下场景:
- 通用工具或框架:如调试器、序列化框架、消息检查工具等,使用反射可以处理多种不同的消息类型。
- 不确定消息类型的情况下:如当消息的类型在运行时才能确定时(例如在 RPC 系统中使用动态消息分发)。
const google::protobuf::Descriptor* descriptor = echo::EchoRequest::descriptor();
std::cout << descriptor->name(); // 打印消息名称
- 在这个例子中,
descriptor()方法返回的是EchoRequest消息的描述符,通过它可以获取消息的名称、字段的数量等信息。
echo::EchoRequest req;
req.set_msg("Hello, World!");// 返回反射对象
const google::protobuf::Reflection* reflection = req.GetReflection();
// 通过字段名称获取 FieldDescriptor
const google::protobuf::FieldDescriptor* field = req.descriptor()->FindFieldByName("msg");// 通过反射获取字段的值
std::string value = reflection->GetString(req, field);
std::cout << "msg field value: " << value << std::endl;
反射对象通过描述符与消息的实际实例交互。通过反射对象,你可以在运行时获取和设置消息字段的值,而不需要直接访问消息对象的成员函数。
其他常用的反射操作:
// 获取字段值
int32_t id_value = reflection->GetInt32(message, field_descriptor);// 设置字段值
reflection->SetString(&message, field_descriptor, "New Value");// 检查字段是否已设置
if (reflection->HasField(message, field_descriptor)) {// 字段已设置
}// 清除字段
reflection->ClearField(&message, field_descriptor);
// 看起来还是要知道字段名和类型。
2.1 动态消息遍历
const google::protobuf::Descriptor* descriptor = req.descriptor();
const google::protobuf::Reflection* reflection = req.GetReflection();for (int i = 0; i < descriptor->field_count(); ++i) {const google::protobuf::FieldDescriptor* field = descriptor->field(i);if (field->type() == google::protobuf::FieldDescriptor::TYPE_STRING) {std::string value = reflection->GetString(req, field);std::cout << field->name() << ": " << value << std::endl;}
}
使用 field_count() 获取消息的字段总数,然后遍历每个字段,检查字段类型并获取其值。
// 但感觉这里有点怪怪的,reflection指针是从req返回的,但是reflection调用自己成员函数的时候还要把req传进去。
相关文章:
pb生成文件和反射
1.protoc生成文件 指定生成的目录和proto文件路径, protoc --cpp_out./ ./echo.proto // echo.proto syntax "proto3";package echo;option cc_generic_services true;message EchoRequest {string msg 1; }message EchoResponse {string msg 2; }…...
.net framework 3.5sp1安装错误卡住不动怎么解决
解决 .NET Framework 3.5 SP1 安装错误卡住的问题,可以尝试以下几种方法: 1.使用 DISM 工具: 将下载的 NetFx3.cab 文件放置在 C:\Windows 文件夹下。 以管理员身份打开命令提示符,输入以下命令: dism /online /En…...
毕业设计—基于 Inception-ResNet模型的皮肤癌分类系统实现
1.摘要 皮肤癌是人类最常见的恶性肿瘤,主要通过视觉诊断进行初步临床筛查。但是由于皮肤病变外观的细微变化性,使用图像自动分类皮肤病变是一项具有挑战性的任务。本文为了提高深度学习算法在皮肤病检测上的准确率,本文提出了基于Inception和…...
什么是优秀的单元测试?
阅读本文之前,请投票支持这款 全新设计的脚手架 ,让 Java 再次伟大! 单元测试的质量意义 合理编写单元测试,可使团队工程师告别牛仔式编程,产出易维护的高质量代码。随着单元测试覆盖率的上升,项目会更加…...
服务器安装Anaconda,Anaconda安装Pytorch
1.服务器安装Anaconda 1.1 下载Anaconda 在服务器上直接下载 wget https://repo.anaconda.com/archive/Anaconda3-2024.06-1-Linux-x86_64.sh1.2 安装Anaconda bash Anaconda3-2024.06-1-Linux-x86_64.sh然后就显示下面:more 安装过程一直enter即可,…...
YOLO目标检测理论详解,YOLOv1理论知识讲解,超w字精读(学习YOLO框架必备),全网最详细教程
文章目录 前言一、目标检测理论1.目标检测发展史2.目标检测框架理论基础3.本章小结 二、YOLOv1理论知识1.YOLOv1网络结构2.YOLOv1检测原理3.YOLOv1的训练流程(1)边界框的位置参数(2)边界框的置信度(3)类别置…...
SpringBoot3.x和OCR构建车牌识别系统
本专题旨在展示 OCR 技术与 SpringBoot3.x 框架结合的广泛应用。我们会深入探讨它在医疗、金融、教育、交通、零售、公安等多个领域的现实应用。每个应用场景都会提供详细的实例、面临问题的分析与解决策略,以帮助您深入理解 OCR 技术在实践中的关键作用。让我们一同…...
conda 容器学习笔记之一 -- 基础环境配置
1、容器瘦身导致部分应用缺少,需要在非容器环境下部署环境。但为避免破坏现有环境,现有使用conda环境进行隔离管理 创建:conda create -n tts python3.10.0 2、conda 是python环境管理,和python无关的东西比如cann还是会影响 下载…...
Oracle分区表改造(三):通过分区交换和分裂改造为分区表
Oracle分区表改造(三):通过分区交换和分裂改造为分区表 源表数据准备范围分区表改造:非间隔分区创建普通分区表分区交换分区分裂范围分区表改造:间隔分区创建间隔分区表分区交换分区分裂表重命名🐬 创建只有一个分区的分区表, 通过分区交换将原表变成分区表,然后分裂分…...
LeetCode 0908.最小差值 I:思维(遍历)
【LetMeFly】908.最小差值 I:思维(遍历) 力扣题目链接:https://leetcode.cn/problems/smallest-range-i/ 给你一个整数数组 nums,和一个整数 k 。 在一个操作中,您可以选择 0 < i < nums.length 的…...
Python基础之循环语句
在Python的编程世界里,循环结构犹如一把神奇的钥匙,开启高效处理数据和重复执行任务的大门。它赋予程序员强大的力量,让代码充满活力。Python主要有两种类型的循环语句:for循环和while循环。 一、for循环 for循环通常用于遍历一个…...
项目管理软件真的能让敏捷开发变得更简单吗?
敏捷开发是一种以快速交付和适应变化为核心特点的软件开发方法。其特点包括尽早并持续交付、能够驾驭需求变化、版本周期内尽量不加任务、业务与开发协同工作、以人为核心、团队配置敏捷等。 例如,尽早并持续交付可使用的软件,使客户能够更早地体验产品…...
互联网名称之时间戳
什么是时间戳 时间戳(Timestamp)是一种用于表示特定时刻的数值或字符串,通常以日期和时间的形式出现。它用于记录某一事件发生的准确时间,在计算机系统中常被用于日志记录、数据处理和同步等场景。 常见的时间戳 在互联网中常见…...
Leetcode—1242. 多线程网页爬虫【中等】Plus(多线程)
2024每日刷题(187) Leetcode—1242. 多线程网页爬虫 实现代码 /*** // This is the HtmlParsers API interface.* // You should not implement it, or speculate about its implementation* class HtmlParser {* public:* vector<string>…...
RISC-V笔记——内存模型总结
1 前言 Memory consistency model定义了使用Shared memory(共享内存)执行多线程(Multithread)程序所允许的行为规范。RISC-V使用的内存模型是RVWMO(RISC-V Weak Memory Ordering),RVWMO内存模型是根据全局内存顺序(global memory order)定义的,全局内存…...
后端常用安全措施
一、限流 1.简介 限流就是限制流量,但这里的流量是一个比较笼统的概念。如果考虑各种不同的场景,限流是非常复杂的,而且和具体的业务规则密切相关 通过限流,可以控制服务请求的速率,从而提高系统应对突发大流量的能…...
虚拟机数据恢复—通过拼接数据库页碎片的方式恢复数据库的数据恢复案例
虚拟机数据恢复环境: 某品牌服务器通过同品牌某型号的RAID卡,将4块STAT硬盘为一组RAID10阵列。上层部署XenServer虚拟化平台,虚拟机安装Windows Server系统,每台虚拟机有两个虚拟机磁盘(系统盘 数据盘)&am…...
【vue】自封组件,基于vue2封装一个弹框组件
源码:https://download.csdn.net/download/galaxyJING/89913551...
ES6基础知识
一、定义变量的关键字let和const 1. let 定义变量的语法: let 变量名 值; 2. 和var定义变量的区别 1. 是否支持同一个作用域变量同名 var支持,let不支持 2. 是否支持预解析 var支持,let不支持 3. 是否会挂载在window对象…...
基于Multisim的模拟拔河游戏比赛设计与仿真
1.设计一个模拟拔河游戏比赛的逻辑电路 2.使用15个发光二极管表示绳子,开机后只有最中间的发光二极管亮。 3.比赛双方各持一个按钮,快速不断地按动按钮,产生脉冲,谁按的快,发光的二极管就向谁的方向移动,每…...
从ULN2803芯片内部拆解,聊聊三极管“黄金搭档”达林顿管到底强在哪?
ULN2803芯片拆解:达林顿管如何成为三极管的“黄金搭档”? 当我们需要用单片机的微弱IO口信号(通常只有几毫安)驱动继电器、电机这类“大胃王”负载时,就像试图用一根吸管给游泳池注水——理论可行,实际效率…...
GLM-4-9B-Chat-1M惊艳效果:碳中和白皮书(120页)中的技术路径拆解、时间节点校验与政策匹配度评分
GLM-4-9B-Chat-1M惊艳效果:碳中和白皮书(120页)中的技术路径拆解、时间节点校验与政策匹配度评分 1. 项目背景与核心能力 今天要给大家展示一个让人眼前一亮的技术应用场景——用GLM-4-9B-Chat-1M这个本地部署的大模型,来深度分…...
Pixel Couplet Gen 生成效果对比分析:不同参数下的对联质量评估
Pixel Couplet Gen 生成效果对比分析:不同参数下的对联质量评估 1. 引言:当AI遇上传统对联 春节贴对联是中国延续千年的文化传统,但创作一副既工整又有新意的对联并非易事。Pixel Couplet Gen作为一款AI对联生成工具,通过调整Te…...
为什么MedNeXt能超越Transformer?揭秘大卷积核在医学图像分割中的独特优势
MedNeXt如何用大卷积核重塑医学图像分割?技术优势全解析 当你在深夜的医院影像科,看着屏幕上模糊的CT扫描图,试图从那些灰度渐变中分辨出肿瘤边界时,是否会想过AI模型眼中的世界?医学图像分割——这个决定患者治疗方案…...
Optick多线程性能分析:游戏引擎中的并发性能优化实战
Optick多线程性能分析:游戏引擎中的并发性能优化实战 【免费下载链接】optick C Profiler For Games 项目地址: https://gitcode.com/gh_mirrors/op/optick Optick是一款专为游戏开发打造的C性能分析工具,能够精准捕捉多线程应用中的性能瓶颈&…...
Vue 3.4+ 实验性/新特性深度实战(2026版)
一、背景:从“稳定”到“极致体验”截至 2026 年,Vue 3.4 与 3.5 已全面普及,但许多能显著降低心智负担的特性(如 defineModel)在早期被标记为“实验性”,或仅在 3.5 才完全稳定。如果你还在写“Pr…...
元宇宙拆迁队:强拆违规建筑日入十万
从Bug猎人到空间执法官当传统的软件测试工程师还在为揪出一个隐蔽的NullPointerException而欢欣鼓舞时,一片更为广阔、也更为凶险的新战场已经悄然开启——元宇宙。在这里,代码的缺陷不再仅仅导致程序崩溃或数据丢失,它们会具象化为扭曲的空间…...
5分钟快速上手:AsrTools智能语音转文字工具全攻略
5分钟快速上手:AsrTools智能语音转文字工具全攻略 【免费下载链接】AsrTools ✨ AsrTools: Smart Voice-to-Text Tool | Efficient Batch Processing | User-Friendly Interface | No GPU Required | Supports SRT/TXT Output | Turn your audio into accurate text…...
警惕!新型U盘蠕虫伪装文档传播:实测火绒5.0查杀+防御全攻略
深度解析U盘蠕虫病毒:从防御到查杀的全面安全指南 1. 新型U盘蠕虫病毒的运作机制剖析 U盘蠕虫病毒近年来呈现出越来越复杂的传播方式和技术手段。这类病毒通常利用Windows系统的自动播放功能(AutoRun.inf)或注册表劫持技术进行传播࿰…...
忍者像素绘卷镜像免配置部署:自动检测GPU型号并加载最优配置
忍者像素绘卷镜像免配置部署:自动检测GPU型号并加载最优配置 1. 产品概览:打破次元壁的像素艺术工作站 忍者像素绘卷是一款基于Z-Image-Turbo深度优化的图像生成工作站,专为像素艺术创作而设计。它将传统漫画创作与现代AI技术相结合&#x…...
