当前位置: 首页 > news >正文

C++中的静态库与动态库

文章目录

        • 静态库
          • 构建静态库
        • 动态库
          • 构建动态库
        • 它们的不同
        • 参考文章

单独提这个 ,我想我们在coding过程中,可能也会知道一两个词,如 标准库、xx库等。库作为一组已编写好、组织好的、可复用的资源接口,可以被用于其他程序。很不夸张地说,很多程序都需要依赖一些底层依赖库,从而支撑它们完成一些基础工作。

库主要分为两种类型:静态库(static library)动态库(shared library)

静态库

静态库是一个在链接过程中采用静态链接方式链接进可执行文件中的库文件,在静态链接方式中,可执行文件会拷贝静态库中导出的接口并使其成为它的一部分。在Windows系统中它主要是以.lib为后缀,而在Linux系统中,主要以.a为后缀。

构建静态库

项目结构为:

.
├── CMakeLists.txt
├── library.h
├── library.cpp

CMakeLists.txt中的内容为:

cmake_minimum_required(VERSION 3.26)
project(library)
set(CMAKE_CXX_STANDARD 11)
add_library(library STATIC library.cpp)

library.h的内容为:

#ifndef HELLO_LIB_LIBRARY_H
#define HELLO_LIB_LIBRARY_H#include <string>
class   Test {
public:explicit Test(std::string str);std::string  getStr() ;static int getNum() ;
private:std::string str_;static int num; // count value
};void  print();
#endif //HELLO_LIB_LIBRARY_H

library.cpp的内容为:

#include "library.h"#include <iostream>int Test::num = 0; // init
Test::Test(std::string str):str_(std::move(str)) {}
std::string Test::getStr()  {++num;return str_;
}int Test::getNum(){return  num;}

采用cmake进行构建,即可生成对应的静态库文件,在Window环境下将会生成library.lib,而在Linux环境下将会生成liblibrary.a

随后可以在另一个项目中使用它,项目结构为:

.
├── build
├── CMakeLists.txt
├── include
│   └── library.h
├── lib
│   └── library.lib
└── src└── main.cc

CmakeLists.txt的内容为:

cmake_minimum_required(VERSION 3.10)project(lib_test)set(CMAKE_CXX_STANDARD 11)
include_directories(include)
# 增加链接库的搜索路径
link_directories(lib)
# 链接 library库
link_libraries(library)
add_executable(${PROJECT_NAME} src/main.cc)

而随后就可以在main.cc中使用它们了:

#include<iostream>
#include"library.h"
int main()
{Test test("Hello");std::cout << test.getStr();std::cout << Test::getNum();return 0;
}
动态库

动态库也叫做共享库,编译时并不会将所导出的接口拷贝到可执行文件中,而是在运行时才会被程序所引用。在Windows系统中它主要是以.dll为后缀,而在Linux系统中,主要以.so为后缀。需要特别注意的是,在MSVC编译器中,Windows环境下不仅生成dll后缀文件,还会生成.lib文件,该文件此刻的作用是作为一个导入库

构建动态库

项目结构大体上和上述提到的构建的静态库一致,但还需要修改一下CMakeLists以及library.h(针对MSVC编译器,Linux环境、MinGW-gcc不用管)。

library.h文件:

#ifndef HELLO_LIB_LIBRARY_H
#define HELLO_LIB_LIBRARY_H#ifndef EXPORTTING
#define DECLSPEC __declspec(dllimport)
#else
#define DECLSPEC __declspec(dllexport)
#endif // EXPORTTING
#include <string>class DECLSPEC  Test {
public:explicit Test(std::string str);std::string  getStr() ;static int getNum() ;
private:std::string str_;static int num; // count value
};void DECLSPEC  print();
#endif //HELLO_LIB_LIBRARY_H

需要额外的添加__declspec(dllexport)指示这个类/函数是一个可导出类或函数,以便在dll中导出它的接口同时在lib中有对应的符号信息(只有添加了它,MSVC才会生成必需的.lib导入库)。同时在使用这个库的项目中引用相关的头文件也需要添加__declspec(dllimport)来导入所需的数据(没有这个扩展的话,在一些场景时会出现无法解析符号的错误,比如静态数据的导出等),所以为了方便使用同一个头文件,在这里采用一个宏来标识这两者的切换时刻。(构建库时导出(__declspec(dllexport)),使用库时导入(__declspec(dllimport)))

修改CMakeLists文件:

cmake_minimum_required(VERSION 3.26)
project(library)set(CMAKE_CXX_STANDARD 11)
# SHARED 共享库
add_library(library SHARED library.cpp)
# 加入预定义宏 EXPORTTING
add_definitions(-DEXPORTTING )

在对应环境下采用Cmake工具 构建即可得到对应环境下的动态库文件,比如Windows环境下会生成.lib文件和.dll文件,.lib直接和静态库的配置方式一样,在CMakeLists中修改即可,而将.dll文件直接放置在可执行文件同一路径下,即可隐式链接、调用。而在Linux环境中,只会生成一个.so文件,其在其他项目的cmake使用配置与静态库配置一致。

前面提到的cmake工具构建,构建涉及的命令可以归纳为以下步骤:

# 在项目根目录下执行# 创建build目录 并进行构建
cmake -Bbuild# 执行 make 即可完成构建
# 方式一
cd build 
make
# 方式二 build 是构建目录 lib_test 是构建目标名
cmake --build build --target lib_test -j 8
它们的不同
  • 链接时刻不同:静态库会在编译期完成拷贝与链接,而动态库会在运行时按需载入。
  • 可执行文件大小不同:静态库需要整体进行拷贝成为可执行文件的一部分,而动态库无需拷贝多次(拷贝一次,而后其他程序进行共享),故对于同一个库,采用动态链接会使得体积相比静态库更小。
  • 执行速度不同:静态库在编译期间已经完成链接,而动态库则会有额外的动态载入开销,所以相对来说,静态链接库更快。
  • 库更新的影响不同:静态库因为会成为可执行文件的一部分,所以其更新的时候会导致可执行文件也需要重新编译,而动态库只需更新版本即可(接口不变)。
参考文章
  • Linux 中的动态链接库和静态链接库是干什么的? - 知乎 (zhihu.com)
  • c++ - Difference between static and shared libraries? - Stack Overflow
  • 动态库与静态库编译与使用实验 - River’s Blog (riverj.top)

相关文章:

C++中的静态库与动态库

文章目录 静态库构建静态库 动态库构建动态库 它们的不同参考文章 单独提这个 库&#xff0c;我想我们在coding过程中&#xff0c;可能也会知道一两个词&#xff0c;如 标准库、xx库等。库作为一组已编写好、组织好的、可复用的资源接口&#xff0c;可以被用于其他程序。很不…...

UGUI 绘制线段

描述 点击鼠标左键在屏幕上绘制线段 准备 VertexHelper 网格绘制工具类向量、叉乘RectTransformUtility.ScreenPointToLocalPointInRectangleSetVerticesDirtyOnPopulateMesh 思路 鼠标按下&#xff0c;记录线段起点&#xff1b;鼠标持续按下&#xff0c;记录鼠标当前帧的…...

详细学习Mybatis(2)

详细学习Mybatis&#xff08;2&#xff09; 一、Mybatis核心配置文件详细解释1.1 environment&#xff08;环境&#xff09;1.2 事务管理器&#xff08;transactionManager&#xff09;1.3、dataSource&#xff08;数据源&#xff09;1.4、properties1.5、mapper 一、Mybatis核…...

LinkedList与链表

目录 一、Arraylist的缺陷 二、链表 2.1 链表的概念和结构 2.2 链表的实现 三、链表面试题 3.1 删除链表中所有值为val的节点 3.2 反转一个单链表 3.3 链表的中间节点 3.4 将有序链表合并 3.5 输出倒数第k个节点 3.6 链表分割 3.7 链表的回文结构 3.8 找两个链表的公共节…...

纳米软件芯片自动化测试系统测试电源芯片稳压反馈的方法

在一些电源芯片或稳压芯片中&#xff0c;通常内部都会有稳压反馈电路&#xff0c;这些电路可以将输入电压通过内部调整后输出一个稳定的输出电压&#xff0c;以满足电路中的稳定电源需求。也就是说芯片的稳压反馈就是内部稳压反馈电路中的电压。 芯片稳压反馈原理介绍 稳压反馈…...

微信小程序之项目基本结构、页面的基础及宿主环境

文章目录 前言一、基本组成结构基本组成小程序页面的组成部分JSON配置文件作用 二、页面基础pagesWXML和HTML的区别WXSS和CSS的区别小程序中js文件分类 三、小程序宿主环境总结 前言 微信小程序的项目基本结构、页面的基础及宿主环境 一、基本组成结构 基本组成 新建一个微信…...

C/C++鸡尾酒疗法 2023年5月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析

目录 C/C鸡尾酒疗法 一、题目要求 1、编程实现 2、输入输出 二、解题思路 1、案例分析 三、程序代码 四、程序说明 五、运行结果 六、考点分析 C/C鸡尾酒疗法 2020年6月 C/C编程等级考试一级编程题 一、题目要求 1、编程实现 鸡尾酒疗法&#xff0c;原指“高效抗…...

人工智能及大模型简介

一、人工智能介绍 人工智能&#xff08;Artificial Intelligence&#xff09;&#xff0c;英文缩写为AI。它试图赋予机器智能的能力&#xff0c;使它们能够像人类一样思考、学习和做出决策。它的核心要素是数据、模型和算力。   数据是人工智能的基础&#xff0c;数据的质量和…...

基于springboot消防员招录系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…...

手把手教你制作登录、注册界面 SpringBoot+Vue.js(cookie的灵活运用,验证码功能)

一、用户登录界面 实现思路&#xff1a;用户在界面输入用户名和密码传入变量。用post方法传输到后端&#xff0c;后端接收整个实体对象。将用户名提取出。在dao层方法中通过select注解查询&#xff0c;返回数据库对应的数据对象。如果返回为空则return false。不为空则通过比对…...

C++ Qt零基础入门进阶与企业级项目实战教程与学习方法分享

Qt是一个卓越的客户端跨平台开发框架&#xff0c;可以在Windows、Linux、macOS进行客户端开发&#xff0c;无缝切换&#xff0c;一统三端&#xff1b;当然除了桌面端&#xff0c;在移动端的早期&#xff0c;Qt也展现了其多才多艺&#xff0c;在Android和ios也可以使用Qt编写app…...

TypeScript学习记录

一、TS开发环境的搭建 1、下载并安装node.js 2、使用npm全局安装typeScript 进入命令行输入&#xff1a;npm i -g typescript 3、创建一个ts文件 4、使用tsc对ts文件进行编译 进入命令行进入ts文件所在目录执行命令&#xff1a;tsc 文件名.ts 二、TS基本变量 1、类型声…...

vue内置组件Transition的详解

1. Transition定义 Vue 提供了两个内置组件&#xff0c;可以帮助你制作基于状态变化的过渡和动画&#xff1a; <Transition>会在一个元素或组件进入和离开 DOM 时应用动画。 <TransitionGroup> 会在一个 v-for 列表中的元素或组件被插入&#xff0c;移动&#xff0…...

中秋节听夜曲,Android OpenGL 呈现周董专属的玉兔主题音乐播放器

概述 前几天发现QQ音乐有个好玩的功能&#xff0c;为用户提供了多种 播放器主题&#xff0c;其中 原神 的主题让我眼前一亮&#xff1a; 当然&#xff0c;诸如 换肤、主题 类的功能已经屡见不鲜&#xff0c;但这类沉浸式播放器的听歌体验确实不错。 见猎心喜&#xff0c;正好…...

008_第一代软件系统架构

第一代软件系统架构 文章目录 第一代软件系统架构项目介绍软件架构和软件构架系统框架硬件组成运行系统基础库软件层 系统架构 关键字&#xff1a; Qt、 Qml、 关键字3、 关键字4、 关键字5 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&…...

oracle客户端的安装(SQL Developer)

参考资料 软件首页&#xff1a;https://www.oracle.com/database/sqldeveloper/ 官方文档&#xff1a;https://docs.oracle.com/en/database/oracle/sql-developer/ 下载地址&#xff1a;https://www.oracle.com/database/sqldeveloper/technologies/download/ 安装指南&#…...

Mysql索引优化1

关闭查询缓存 set global query_cache_size 0; set global query_cache_type 0; force index&#xff08;索引&#xff09;where 条件 强制走索引 一般不推荐&#xff0c;因为mysql结构中会通过cost计算出最优sql路线 索引下推 5.6之前 会先从辅助索引表也就是二级索引…...

Spring常考知识点(IOC、事务、容器等)

作者&#xff1a;逍遥Sean 简介&#xff1a;一个主修Java的Web网站\游戏服务器后端开发者 主页&#xff1a;https://blog.csdn.net/Ureliable 觉得博主文章不错的话&#xff0c;可以三连支持一下~ 如有需要我的支持&#xff0c;请私信或评论留言&#xff01; Spring需要理解的问…...

Leetcode 2867. Count Valid Paths in a Tree

Leetcode 2867. Count Valid Paths in a Tree 1. 解题思路2. 代码实现 题目链接&#xff1a;2867. Count Valid Paths in a Tree 1. 解题思路 这一题思路上的话由于要求路径上有且仅有一个质数点&#xff0c;因此&#xff0c;一个直接的思路就是考察所有质数的点作为中心点时…...

Jtti:Ubuntu下如何创建XFS文件系统的LVM

在 Ubuntu 下创建一个 XFS 文件系统的 LVM&#xff08;Logical Volume Manager&#xff09;分区需要一系列步骤。以下是详细的步骤&#xff1a; 1. 创建物理卷 (PV) 首先&#xff0c;将要用于 LVM 的硬盘分区&#xff08;物理卷&#xff09;初始化为物理卷。假设你有一个硬盘…...

做销售管理分析需要看哪些关键指标?

做销售管理分析需要看哪些关键指标&#xff1f; 销售管理分析时抓取关键指标&#xff0c;有着能够【分析和判断销售趋势、为销售决策提供数据支持、优化销售流程和客户管理】等的好处 在了解了分析关键指标的目的之后&#xff0c;我们就可以根据企业的需求来确定关键指标&…...

【Python】自动完成手写字体图片贴入以及盖章工具

简介 该工具完成了如下功能&#xff1a; 1.将文字转换为手写体填入到模板文件中 2.自动将文字转换为盖章格式填入到模板文件中 3.字体格式可以替换 4.有配置文件进行扩展功能 功能模块 1.界面模块 import sys from PyQt5.QtWidgets import QApplication, QMessageBox, QWid…...

基于Xml方式Bean的配置-初始化方法和销毁方法

SpringBean的配置详解 Bean的初始化和销毁方法配置 Bean在被实例化后&#xff0c;可以执行指定的初始化方法完成一些初始化的操作&#xff0c;Bean在销毁之前也可以执行指定的销毁方法完成一些操作&#xff0c;初始化方法名称和销毁方法名称通过 <bean id"userService…...

实时更新进度条:JavaScript中的定时器和异步编程技巧

前言 在Web开发中&#xff0c;有许多场景需要实时地更新页面上的进度&#xff0c;例如上传文件、数据处理等。本文将介绍如何利用JavaScript中的定时器和异步编程技巧来实现实时更新进度&#xff0c;并探讨一些其他解决方案。 处理进度实时更新&#xff1a; 利用异步编程实现实…...

【简单图论】CF898 div4 H

Problem - H - Codeforces 题意&#xff1a; 思路&#xff1a; 手玩一下样例就能发现简单结论&#xff1a; v 离它所在的树枝的根的距离 < m 离这个根的距离时是 YES 否则就是NO 实现就很简单&#xff0c;先去树上找环&#xff0c;然后找出这个根&#xff0c;分别给a 和…...

【大虾送书第十一期】适合新手自学的网络安全基础技能“蓝宝书”:《CTF那些事儿》

目录 &#x1f96e;写在前面 &#x1f96e;内容简介 &#x1f96e;读者对象 &#x1f96e;专家推荐 &#x1f96e;目录 &#x1f96e;文末福利 &#x1f990;博客主页&#xff1a;大虾好吃吗的博客 &#x1f990;专栏地址&#xff1a;免费送书活动专栏地址 写在前面 CTF比赛是快…...

IDEA安装离线插件后重启无法打开

解决方法 1.找到插件安装目录删除插件 插件的位置一般在C:\Users\19058\AppData\Roaming\JetBrains\IntelliJIdea2021.1\plugins 高亮部分是自己电脑的用户位置&#xff0c;把报错前的刚才最新安装的插件删除&#xff0c;再尝试打开idea即可解决该问题 2.补充说明 AppData是个隐…...

论软件的可靠性设计

摘要 2021年6月&#xff0c;我所在的公司中标某集团保险大数据平台一体化研发项目&#xff0c;该项目总投资2000万人民币&#xff0c;项目周期为2年&#xff0c;通过该项目&#xff0c;搭建该集团保险大数据平台&#xff0c;一方面将全国所有保险业务全部入库并保存&#xff0…...

AG35学习笔记(一):debug串口抓取模组log、debug串口测试AT指令、echo命令通过串口发送16进制数据

目录 一、概述二、抓取模组log2.1 硬件接口2.2 用户登录2.3 相关指令 三、测试AT指令3.1 查看端口3.2 进入模式 四、串口发16进制echo使用 一、概述 二、抓取模组log 在之前记录了通过USB&#xff0c;使用移远工具Qwinlog来抓取log&#xff08;3.3 抓取模组log&#xff09;。…...

Python进阶学习----一闭三器

目录 ​编辑 前言 一.三器 1. 迭代器&#xff08;Iterator&#xff09; 1.1 什么是可迭代对象 1.2什么是迭代器 1.3案例演示&#xff1a; 以下是一个简单的迭代器示例&#xff0c;遍历一个列表并打印每个元素&#xff1a; 1.4迭代器总结 2. 生成器&#xff08;Generat…...