使用CMake生成动态链接库(.dll和.so)和静态链接库(.lib和.a)的方法

news2024/10/22 23:14:16

(一)简介

对于大型软件开发,动态连接库是必不可少的。不仅可以实现模块的封装,而且可以实现软件的热更新(即替换windows下的.dll或Linux下的.so文件后直接实现软件更新,无需重新编译)。有时也需要使用静态链接库,在一定程度上相比于动态链接库运行速度更快。

本文介绍使用CMake生成以及调用动态连接库和静态链接库的方法,只关注易出错的地方,完整项目demo代码见https://download.csdn.net/download/weixin_43325228/89913651。

(二)Windows系统

在windows系统中,我们使用visual studio 2022编译器编译.dll文件和.lib文件

(1)动态链接库 dll

visual studio 2022编译器最大的特点是不会自动导出代码中的符号(需要额外设置),所以务必指明需要导出那些符号。既可以使用.def文件指明,也可以用__declspec(dllexport)指明,通常建议采用第二种方式:

extern "C" __declspec(dllexport) void initMyClass(double num);
extern "C" __declspec(dllexport) void addToMyInt(int num);
extern "C" __declspec(dllexport) void printMyInt();

简单言之,需要在函数声明(或变量声明)的前方写上__declspec(dllexport),以表示需要导出符号。特别地,前缀extern "C" 表示导出标准的C语言符号,也就是说导出“干净的”C语言符号而非添加了修饰的“不干净”的C++语言符号。这样有助于规范接口,提升兼容性,实现大型软件的松耦合和热更新。

※ 如何判断是否导出了“干净的”C语言符号呢?

可以用记事本打开编译后的dll文件,如果发现函数名称后面有一些后缀,则说明没有使用extern "C"
在这里插入图片描述如果函数名称后面没有后缀,则说明使用了extern "C"
在这里插入图片描述CMake构建项目时需要指明生成动态链接库SHARED(否则默认是静态的),CMakeLists.txt文件如下

project(buildDynamicLink)

set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin)

add_library(buildDynamicLink SHARED API.cpp myClass.cpp)

这样就可以完成dll的编译了
通常会得到三个文件,.dll是运行时需要,包含了算法的实现,.lib是编译时需要,包含了符号,.exp没用。需要注意的是这里的.lib与后文讲的静态链接库不同,只是供编译器查找符号并链接用的,不包含算法的具体实现内容
在这里插入图片描述

※ 如何使用dll呢?

如果要使用dll,首先需要拿到接口头文件

extern "C" __declspec(dllimport) void initMyClass(double num);
extern "C" __declspec(dllimport) void addToMyInt(int num);
extern "C" __declspec(dllimport) void printMyInt();

其次编写CMakeLists.txt文件

project(useDynamicLink)

set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin)

add_executable(useDynamicLink main.cpp)

target_link_libraries(useDynamicLink buildDynamicLink)

这里的target_link_libraries用于指明需要链接那些库,buildDynamicLink是指buildDynamicLink.lib文件而非buildDynamicLink.dll文件

编译完成之后所得的exe文件需要配合dll文件才能正常使用,否则会报错:找不到dll。通常将dll放在与exe同一个目录下

(2)静态库 lib

与动态链接库不同,visual studio 2022编译器编译静态库时会自动导出所有符合。因此不需要人工声明哪些符号需要导出,但是依然建议使用extern "C"增加兼容性

extern "C" void initMyClass(double num);
extern "C" void addToMyInt(int num);
extern "C" void printMyInt();

CMakeLists.txt文件如下

project(buildStaticLib)

set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin)

add_library(buildStaticLib STATIC API.cpp myClass.cpp)

编译后会得到一个lib文件
在这里插入图片描述

※ 如何使用lib呢?

如果要使用lib,首先需要拿到接口头文件

extern "C" void initMyClass(double num);
extern "C" void addToMyInt(int num);
extern "C" void printMyInt();

其次编写CMakeLists.txt文件

project(useStaticLib)

set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin)

add_executable(useStaticLib main.cpp)

target_link_libraries(useStaticLib buildStaticLib)

最终编译得到的exe通常会比lib文件大,这是因为静态库的原理就是将lib嵌入到exe中。这也就意味着如果lib文件变化了,需要重新编译exe才能得到更新。相比较而言,如使用动态链接库方案,如果dll文件变化了而接口没变,那么直接用新的dll文件替换旧的dll文件即可完成热更新,无需重新编译exe。

(三) Linux系统

在linux系统中,我们使用gcc编译器编译.so文件和.a文件

(1)动态链接库 so

gcc编译器的最大特点是自动将所有符号导出,所以不用(也不能)写__declspec(dllexport)语句。当然,还是建议接口符号添加extern "C"前缀以提升兼容性。

extern "C" void initMyClass(double num);
extern "C" void addToMyInt(int num);
extern "C" void printMyInt();

在这里插入图片描述

其余部分与windows类似,编译后只会得到一个文件libbuildDynamicLink.so,so文件的使用方法与dll类似

(2)静态库 a

Linux的静态库编译和使用方法与Windows类似,会形成一个文件libbuildStaticLib.a
在这里插入图片描述
其余部分与windows类似,不再赘述

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

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

相关文章

力扣 困难 52.N皇后II

文章目录 题目介绍题解 题目介绍 题解 法一:返回51题N皇后List的长度 法二: class Solution {private int n, ans;private boolean[] onPath, diag1, diag2;public int totalNQueens(int n) {this.n n;onPath new boolean[n];diag1 new boolean[n * …

Standard IO

为了提高可移植性,将通用IO接口经过再封装就形成了标准IO,标准IO不仅适用于Unix环境,也兼容非Unix环境,这也是为什么说我们应该尽可能的使用标准IO,通用IO通过文件描述符fd来与文件交互,为了以示区分&#…

element plus e-table表格中使用多选,当翻页时已选中的数据丢失

摘要: 点击第一页选中两个,再选择第二页,选中,回到第一页,之前选中的要保留! element ui table 解决办法: :row-key“getRowKeys” (写在el-table中) methods中声明 ge…

多一DY4100数字式接地电阻测试仪使用测量方法

接地电阻二线法测量步骤 1、找出一套简易测试线,一根红色两插头线和一根短绿线; 2、找出一根辅助地钉,距离被测接地桩/扁铁约五米远整根打下去; 3、绿线插头接仪器E孔(绿色孔),夹子夹需测的接…

ArcGIS002:软件自定义设置

摘要:本文详细介绍安装arcgis10.2后软件自定义设置内容,包括工具条的启用、扩展模块的启用、如何加载项管理器、快捷键设置、样式管理器的使用以及软件常规设置。 一、工具条的启用 依次点击菜单栏【自定义】->【工具条】,根据工作需求勾…

医院信息化与智能化系统(5)

医院信息化与智能化系统(5) 这里只描述对应过程,和可能遇到的问题及解决办法以及对应的参考链接,并不会直接每一步详细配置 如果你想通过文字描述或代码画流程图,可以试试PlantUML,告诉GPT你的文件结构,让他给你对应的…

【漏洞修复/安全补丁】5.4之前版本通过api/products接口进行sql注入的问题

5.4之前版本,会使用api/products接口的selectId参数进行sql注入 修复办法 1、修改crmeb/app/api/controller/v1/store/StoreProductController.php文件中的lst方法里面的接收参数,修改成下图 如果你的版本没有coupon_category_id参数的话,…

No.19 笔记 | WEB安全 - 任意文件操作详解 part 1

1. 任意文件上传漏洞基础 什么是文件上传功能? 在网站和应用中,我们经常会看到允许用户上传文件的功能,比如: 更换头像:让用户上传自己的照片作为头像发布图片:在社交媒体或论坛上传图片提交文档:在办公系统中上传Word、Excel等文档 这些都是常见的文件上传功能。 任意文…

Kettle9.4支持Clickhouse数据源插件开发以及性能测试

前言 最近业务这边有个指标需要用到大数据这边的列式数据库进行处理,由于kettle不支持clickhouse数据源驱动,这里查了一下网上的相关资料,发现了一些别人开发好的驱动包,下载下来后使用效果不尽人意。总结下来有以下几个问题&…

重生之“我打数据结构,真的假的?”--1.顺序表(无习题)

C语言中的顺序表详细总结 1. 概述 顺序表(Sequential List)是一种线性数据结构,用于存储具有相同数据类型的一组元素。顺序表采用一段连续的存储空间,使用数组来实现,能够高效地支持随机访问操作。在 C 语言中&#…

基于ssm的校园车辆管理系统的设计与实现

文未可获取一份本项目的java源码和数据库参考。 一、选题背景与意义 (一)选题背景 自改革开放以来,国家开始加大力度对高等校园进行投入,深化了教育体制的改革,全国许多高等校园应运而生,越来越多的孩子走…

C++ —— 《模板进阶详解》,typedef和class的区别以及用法,非类型模板参数,模板的特化,模板的分离编译

目录 1.非类型模板参数 2.模板特化 2.1 概念 2.2 函数模板特化 2.3 类模板特化 2.3.1 全特化 2.3.2 偏特化 3 模板分离编译 3.1 什么是分离编译 3.2 模板的分离编译 4.模板总结 在讲解模板进阶之前,我想先简单单独聊聊class和typename的用法 我们在平时…

Mac使用Git仓库上传文件夹方法

环境:mac 仓库:GitLink Q: 首先我们先了解到,远程下载(用ssh)仓库会默认下载到电脑的哪里呢? A: 如下图,路径为/Users/bb,(bb是我的用户名) 那么我们在将a文…

筑牢理性防线,“卡游启智,理性护航”青少年健康消费倡议发布

新华网北京10月22日电(记者周靖杰)10月21日,国内针对青少年卡牌盲盒消费的倡议在京发布。 “卡游启智,理性护航”青少年健康消费倡议在京正式发布 近年来,卡牌盲盒在青少年中悄然流行,买卡、拆包、集卡成为…

临时配置linux Bridge网桥

Linux Bridge(网桥)是用纯软件实现的虚拟交换机,有着和物理交换机相同的功能,例如二层交换,MAC地址学习等。因此我们可以把tun/tap,veth pair等设备绑定到网桥上,就像是把设备连接到物理交换机上…

数据可视化示例

用eclipse软件 java 代码&#xff1a; <!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <!-- 引入ECharts脚本&#xfe63;-> <script src"js/echarts.js"></script> <title&#xff1e;网格…

红日靶场(三)1、环境介绍及环境搭建

1、靶场介绍 红日靶场03是一个用于安全测试和渗透测试的虚拟化环境&#xff0c;可以帮助用户通过模拟攻击和防御场景来提升网络安全技能。该靶场包含了多个虚拟机和网络配置&#xff0c;用户可以在其中进行各种安全测试活动&#xff0c;如信息收集、漏洞利用、权限提升等。 2…

Java项目-基于Springboot的高校党务系统项目(源码+说明).zip

作者&#xff1a;计算机学长阿伟 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、ElementUI等&#xff0c;“文末源码”。 开发运行环境 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBoot、Vue、Mybaits Plus、ELementUI工具&#xff1a;IDEA/…

ACL访问控制

要求&#xff1a; PC1与PC2不能通信。PC1可以和PC3通信。PC2可以和PC3通信。 1. VLAN配置 根据拓扑图的连接&#xff0c;PC1、PC2、PC3属于不同的VLAN。我们需要确保交换机上的端口已经正确划分到不同的VLAN。假设交换机接口的VLAN配置已经完成&#xff08;其他博文有)&…

在VMware中安装LInux

1.打开VMware选择新建虚拟机 2.这里建议初学者选择“典型&#xff08;推荐&#xff09;”。 3.已提前准备好 Linux 系统的映像文件&#xff08;.iso 文件&#xff09;&#xff0c;此处可选择“安装程序光盘映像文件”&#xff0c;并通过“浏览”按钮找到要安装 Linux 系统的 i…