【C++】替代--whole-archive的一种方式

上篇文章《C++自动注册的工厂与--whole-archive》提到了--whole-archive选项在自动工厂示例的必要,“貌似也没其他方法了”。

这篇文章介绍另一种可以替代的方式,并分析其优缺点,采用的代码示例同上篇文章。文章最后附代码。

方法介绍

ld链接器提供了另外一组选项解决符号依赖的问题。

-u symbol
--undefined=symbol

上面的选项用来告诉链接器symbol符号在最终的输出文件里是未定义的,需要从其他模块拉进去。

这样我们就可以指定依赖的符号,让链接器强制将pay_handler.cpp生成的目标文件链接到可执行文件。

怎么找符号

由于C++允许函数重载,函数名不具有唯一性,编译器需要对名字进行改编,也就是name mangling。所以不能简单的将函数名写在链接选项后面,需要指定实际改编后的符号。

pay_handler.cpp文件如下:

#include "msg_handler.h"
#include <stdio.h>class PayHandler {public:PayHandler() { register_msg_handler("pay", PayHandler::handle);}static bool handle(std::string_view msg_data) {printf("pay handle\n");return true;}
};static PayHandler pay_handler;

假设我们要找handle函数的符号,整个流程如下:
(1)编译pay_handler.cpp为目标文件,符号信息都存储在目标文件里

$ g++ -c pay_handler.cpp
(2)使用nm获取所有符号,结合grep命令搜索疑似符号
$ nm -g pay_handler.o | grep handleU _Z20register_msg_handlerPKcSt8functionIFbSt17basic_string_viewIcSt11char_traitsIcEEEE
0000000000000000 W _ZN10PayHandler6handleESt17basic_string_viewIcSt11char_traitsIcEE
0000000000000000 W _ZNSt17_Function_handlerIFbSt17basic_string_viewIcSt11char_traitsIcEEEPS4_E10_M_managerERSt9_Any_dataRKS7_St18_Manager_operation
0000000000000000 W _ZNSt17_Function_handlerIFbSt17basic_string_viewIcSt11char_traitsIcEEEPS4_E9_M_invokeERKSt9_Any_dataOS3_
(3)使用c++filt命令还原改编之前的符号,确定最终的符号
$ c++filt _ZN10PayHandler6handleESt17basic_string_viewIcSt11char_traitsIcEE
PayHandler::handle(std::basic_string_view<char, std::char_traits<char> >)
最终的CMakeList.txt如下:
cmake_minimum_required (VERSION 3.24.0)
project(main)add_library(payhandler STATIC pay_handler.cpp)
add_library(msghandler STATIC msg_handler.cpp)add_executable(${PROJECT_NAME} main.cpp)target_link_libraries(${PROJECT_NAME}msghandlerpayhandler-u_ZN10PayHandler6handleESt17basic_string_viewIcSt11char_traitsIcEE
)

优劣分析

两个方面分析:

  • 跨编译器

cmake内置支持--whole-archive,所以可以跨编译器,而本篇介绍的选项需要指定符号,而符号是跟具体编译器相关的,所以不具备跨编译器的能力。

  • 对文件大小的影响

--whole-archive会将静态库的所有目标文件链接进来,最终的输出文件可能会比较大;而本篇介绍的选项则只加载符号所依赖的目标文件。

所以要综合考虑以上两个方面选择适合的选项。

附代码

msg_handler.h

#include <functional>
#include <string_view>using MsgHandler = std::function<bool(std::string_view msg_data)>;// 注册消息处理器 
void register_msg_handler(const char *msg_type, MsgHandler handler);// 获取指定消息类型的处理器
MsgHandler* get_msg_handler(const char *msg_type);

msg_handler.cpp

#include <map>
#include <string>#include "msg_handler.h"static std::map<std::string, MsgHandler>& get_map() {static std::map<std::string, MsgHandler> map_handlers;return map_handlers;
}void register_msg_handler(const char *msg_type, MsgHandler handler) {get_map()[msg_type] = handler;
}MsgHandler* get_msg_handler(const char *msg_type) {auto& m = get_map();auto it = m.find(msg_type);if (it != m.end()) {return &it->second;}else {return nullptr;}
}

pay_handler.cpp

#include "msg_handler.h"
#include <stdio.h>class PayHandler {public:PayHandler() { register_msg_handler("pay", PayHandler::handle);}static bool handle(std::string_view msg_data) {printf("pay handle\n");return true;}
};static PayHandler pay_handler

main.cpp

#include "msg_handler.h"
#include <stdio.h>int main() {MsgHandler* handle = get_msg_handler("pay");if (handle) {(*handle)("test data");}else {printf("not found\n");}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/142581.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python+Qt多点最短路径(最优路径)算法实现

程序示例精选 PythonQt多点最短路径(最优路径)算法实现 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对《PythonQt多点最短路径(最优路径)算法实现》编写代码&#xff0c;代码整洁&#xff0…

Qt执行带参sql

//准备执行的sql语句&#xff0c;此为带参的sql语句query.prepare("update employee set Name:Name, Gender:Gender,Height:Height,"" Birthday:Birthday, Mobile:Mobile, Province:Province,"" City:City, Department:Department, Education:Educati…

Android 透明度设置

目录 一、透明度对照表 二、透明度介绍 三、透明度设置 3.1 xml设置 3.2 代码设置 一、透明度对照表 注&#xff1a;00是完全透明&#xff0c;FF就是完全不透明 我们的UI小姐姐就喜欢给「不透明度」&#xff0c;这个需要自己判断一下。 完全透明:0% HEX: 00 透明度:1%…

MR混合现实情景实训教学系统模拟历史情景

二、应用场景 1. 古代战争场景&#xff1a;通过MR混合现实情景实训教学系统&#xff0c;学生可以亲身体验古代战争的场景&#xff0c;如战场布置、战术运用等。这不仅有助于学生更好地理解古代战争的特点&#xff0c;还能够培养他们的团队协作和战略思维能力。 2. 历史文化古…

SparkSQL数据的加载与保存

1 读取和保存文件 SparkSQL读取和保存的文件一般为三种&#xff0c;JSON文件、CSV文件和列式存储的文件&#xff0c;同时可以通过添加参数&#xff0c;来识别不同的存储和压缩格式。 1.1 CSV文件 1&#xff09;代码实现 package com.atguigu.sparksql; import com.atguigu.spar…

vscode+python开发之虚拟环境和解释器切换

需求情景&#xff1a; 现在我们要开发多个项目比如&#xff1a;项目A&#xff0c;项目B、项目C&#xff0c;他们每个项目需要依赖不同的库。每个项目依赖的解释器也不一样怎么办&#xff1f; 项目A&#xff1a;需要在python3.7环境运行 依赖aadd3.2库 项目B、需要在python3.11…

C/C++轻量级并发TCP服务器框架Zinx-框架开发001: 读取标准输入,回显到标准输出

文章目录 完整代码实现参考-非项目使用项目使用的代码 - 乱-但是思路与上面的相同创建Kernel类添加删除修改epoll&#xff0c;才能写run方法创建stdin_Channel类在Kernel类中实现run方法 完整代码实现参考-非项目使用 #include <errno.h> #include <signal.h> #in…

2024上海国际智能驾驶技术展览会(自动驾驶展)

2024上海国际智能驾驶技术展览会 2024 Shanghai International Autonomous driving Expo 时间&#xff1a;2024年3月26-28日 地点&#xff1a;上海跨国采购会展中心 随着科技的飞速发展&#xff0c;智能驾驶已经成为了汽车行业的重要趋势。在这个时代背景下&#xff0c;汽车不…

Ansys Lumerical | 用于增强现实系统的表面浮雕光栅

在本示例中&#xff0c;我们使用 RCWA 求解器设计了一个斜面浮雕光栅 (SRG)&#xff0c;它将用于将光线耦合到单色增强现实 (AR) 系统的波导中。光栅的几何形状经过优化&#xff0c;可将正常入射光导入-1 光栅阶次。 然后我们将光栅特性导出为 Lumerical Sub-Wavelength Model …

数字媒体技术基础之:常见图片文件格式

在数字图像处理和图形设计领域&#xff0c;了解不同的图片文件格式及其特点是至关重要的。每种格式都有其独特的用途和优势。以下介绍一些最常见的图片文件格式。 JPEG Joint Photographic Experts Group 扩展名&#xff1a;.jpg 或 .jpeg 特点&#xff1a; 1、有损压缩&#x…

【Proteus仿真】【51单片机】拔河游戏设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真51单片机控制器&#xff0c;使用按键、LED、动态数码管模块等。 主要功能&#xff1a; 系统运行后&#xff0c;指示灯处于中间位置&#xff0c;数码管显示得分0&#xff0c;当按下…

20231114在HP笔记本的ubuntu20.04系统下向RealmeQ手机发送PDF文件

20231114在HP笔记本的ubuntu20.04系统下向RealmeQ手机发送PDF文件 2023/11/14 14:11 手机&#xff1a;Realme Q 笔记本电脑&#xff1a;HP https://item.jd.com/100012583174.html 惠普&#xff08;HP&#xff09;战66 三代AMD版 14英寸轻薄笔记本电脑&#xff08;锐龙7nm 六核…

多维时序 | MATLAB实现PSO-LSTM-Attention粒子群优化长短期记忆神经网络融合注意力机制的多变量时间序列预测

多维时序 | MATLAB实现PSO-LSTM-Attention粒子群优化长短期记忆神经网络融合注意力机制的多变量时间序列预测 目录 多维时序 | MATLAB实现PSO-LSTM-Attention粒子群优化长短期记忆神经网络融合注意力机制的多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果…

数据拟合、参数估计、插值等数据处理算法

介绍 数据拟合&#xff1a; 数据拟合是通过选择或构建合适的函数模型&#xff0c;将给定的数据点与该函数模型进行匹配和拟合的过程。常见的数据拟合方法包括最小二乘法和非线性最小二乘法。最小二乘法通过最小化实际数据与拟合函数的残差平方和来求解最优拟合参数。非线性最小…

HTTP/2.0协议详解

前言 HTTP/2.0&#xff1a;互联网通信的革新标准 随着互联网技术的飞速发展&#xff0c;HTTP协议作为互联网应用最广泛的通信协议&#xff0c;也在不断演进和优化。HTTP/2.0是HTTP协议的最新版本&#xff0c;它旨在提供更高效、更安全、更快速的互联网连接。 一、HTTP/2.0的…

第一篇 《随机点名答题系统》简介及设计流程图(类抽奖系统、在线答题系统、线上答题系统、在线点名系统、线上点名系统、在线考试系统、线上考试系统)

专栏目录 第一篇 《随机点名答题系统》简介及设计流程图&#xff08;类抽奖系统、在线答题系统、线上答题系统、在线点名系统、线上点名系统、在线考试系统、线上考试系统&#xff09;-CSDN博客 第二篇 《随机点名答题系统》——题库管理详解&#xff08;类抽奖系统、在线答题…

Redis04-分布式锁

目录 Redis实现分布式锁 分布式锁的工作流程 Redis实现分布式锁 Redission的watch dog Redis分布式锁的合理应用 Redis实现分布式锁 在单节点的服务器中&#xff0c;java中的synchronized机制是处于JVM层面的&#xff0c;只能保证线程之间的同步。而实际的服务部署中&…

Spark SQL编程

1. Spark SQL概述 1.1 什么是Spark SQL Spark SQL是用于结构化数据处理的Spark模块。与基本的Spark RDD API不同&#xff0c;Spark SQL提供的接口为Spark提供了有关数据结构和正在执行的计算的更多信息。在内部&#xff0c;Spark SQL使用这些额外的信息来执行额外的优化。与Spa…

解析SQL 获取表、字段及SQL查询参数

解析SQL 获取表、字段及SQL查询参数 1. 执行效果2. 使用2.1 引入依赖2.2 相关实体2.3 工具类 1. 执行效果 2. 使用 2.1 引入依赖 <!-- sql 解析处理--><dependency><groupId>com.github.jsqlparser</groupId><artifactId>jsqlparser</artifa…