如何理解静态库与动态库

article/2025/8/30 6:44:22

究竟什么是库:

日常生活中有很多所谓的库,比如车库啊,优衣库啊,甚至还有一库(日语)咳咳。然后对程序员来说,所谓的库,即是程序库,当一段代码十分耐用,又经过了世人的检验,那么我就说,该程序可以入库,而入库就以为着,你要为世人所用,给世界造福,我们写代码之所以没那么累,就是因为有大量的前辈封装了许许多多的库给我们使用。

标准来说:程序库(library),就是一个可供使用的各种标准程序、子程序、文件以及它们的目录等信息的有序集合。 汇集在一起的经常应用的程序。

库的两种形式

本质上来说库是一种可执行代码的二进制形式,可以直接载入内存执行。库有两种:静态库(.a、.lib)和动态库(.so、.dll)。

所谓静态、动态是指链接时的方式不一样而造成的差异。回顾一下,将一个程序编译成可执行程序的步骤:预编译-》编译-》汇编-》链接-》可执行程序

预编译过程主要做4件事:

①展开头文件
在写有#include 或#include "filename"的文件中,将文件filename展开,通俗来说就是将fiename文件中的代码写入到当前文件中;
②宏替换
③去掉注释
④条件编译
即对#ifndef #define #endif进行判断检查,也正是在这一步,#ifndef #define #endif的作用体现出来,即防止头文件被多次重复引用

编译

将代码转成汇编代码,并且在这个步骤中做了两件很重要的工作:
①编译器在每个文件中保存一个函数地址符表,该表中存储着当前文件内包含的各个函数的地址;
②因为这步要生成汇编代码,即一条一条的指令,而调用函数的代码会被编译成一条call指令,call指令后面跟的是jmp指令的汇编代码地址,而jmp指令后面跟的才是“被调用的函数编译成汇编代码后的第一条指令”的地址,但是给call指令后面补充上地址的工作是在链接的时候做的事情。

汇编

将汇编代码转成机器码

链接

编译器将生产的多个.o文件链接到一起生成一个可执行.exe文件;
但是在这个过程中,编译器做的一个重要的事情是将每个文件中call指令后面的地址补充上;方式是从当前文件的函数地址符表中开始找,如果没有,继续向别的文件的函数地址符表中找,找到后填补在call指令后面,如果找不到,则链接失败。
在这里插入图片描述

静态库

之所以成为【静态库】,是因为在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中。因此对应的链接方式称为静态链接。

试想一下,静态库与汇编生成的目标文件一起链接为可执行文件,那么静态库必定跟.o文件格式相似。其实一个静态库可以简单看成是一组目标文件(.o/.obj文件)的集合,即很多目标文件经过压缩打包后形成的一个文件。静态库特点总结:

  1. 静态库对函数库的链接是放在编译时期完成的。

  2. 程序在运行时与函数库再无瓜葛,移植方便。

  3. 浪费空间和资源,因为所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件。

  4. Linux下使用ar工具、Windows下vs使用lib.exe,将目标文件压缩到一起,并且对其进行编号和索引,以便于查找和检索。

其流程如下图所示:
在这里插入图片描述

动态库

为什么需要动态库,其实也是静态库的特点导致。

  1. 第一个问题是静态库会造成空间的浪费
  2. 另一个问题是静态库对程序的更新、部署和发布页会带来麻烦。如果静态库liba.lib更新了,所以使用它的应用程序都需要重新编译、发布给用户(对于玩家来说,可能是一个很小的改动,却导致整个程序重新下载,全量更新)。

动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题。动态库在程序运行是才被载入,也解决了静态库对程序的更新、部署和发布页会带来麻烦。用户只需要更新动态库即可,增量更新。

在这里插入图片描述
动态库特点总结:

  1. 动态库把对一些库函数的链接载入推迟到程序运行的时期。

  2. 可以实现进程之间的资源共享。(因此动态库也称为共享库)

  3. 将一些程序升级变得简单。

  4. 甚至可以真正做到链接载入完全由程序员在程序代码中控制(显示调用)。

  5. Window与Linux执行文件格式不同,在创建动态库的时候有一些差异。

  6. 在Windows系统下的执行文件格式是PE格式,动态库需要一个DllMain函数做出初始化的入口,通常在导出函数的声明时需要有_declspec(dllexport)关键字。

  7. Linux下gcc编译的执行文件默认是ELF格式,不需要初始化入口,亦不需要函数做特别的声明,编写比较方便。

  8. 与创建静态库不同的是,不需要打包工具(ar、lib.exe),直接使用编译器即可创建动态库。

区别与联系
二者的不同点在于代码被载入的时刻不同。

  1. 静态库的代码在编译过程中已经被载入可执行程序,因此体积比较大。
  2. 动态库(共享库)的代码在可执行程序运行时才载入内存,在编译过程中仅简单的引用,因此代码体积比较小。
    不同的应用程序如果调用相同的库,那么在内存中只需要有一份该动态库(共享库)的实例。
  3. 静态库和动态库的最大区别,静态情况下,把库直接加载到程序中,而动态库链接的时候,它只是保留接口,将动态库与程序代码独立,这样就可以提高代码的可复用度,和降低程序的耦合度。
  4. 静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。
  5. 动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在

参考:https://www.cnblogs.com/mhq-martin/p/11898245.html
https://blog.nowcoder.net/n/8e07e78a703c413c916d0f830b8ceda7


http://chatgpt.dhexx.cn/article/oqcoVLDV.shtml

相关文章

C++静态库与动态库的区别

文章目录 什么是库静态库Linux下创建与使用静态库Windows下创建与使用静态库 动态库Linux下创建与使用动态库Windows下创建与使用动态库 动态库的显式调用在Linux下显式调用动态库在Windows下显式调用动态库显式调用C动态库注意点 附件:Linux下库相关命令g(gcc)编译…

动态库静态库的区别

1、动态库以及静态库区别 静态库是函数和数据编译进一个二进制文件里面(.lib文件),在使用静态库链接成可执行程序的时候,链接器会复制静态库内的函数和数据进可执行程序里面(.EXE文件),所以在加载库的时候不需要加载相…

详谈静态库和动态库的区别

一、什么是库: 库是写好的,现有的,成熟的,可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。 本质上来说,库是一种可执行代…

【C语言】详解#define,#ifdef,#ifndef,#elif,#undef,以及相关运算符

1.明示常量 #define 预处理指令结尾不带;(分号),在预编译的过程中使用宏的地方会进行展开,是用多少次就展开多少次,但是只替换 不计算,预处理器在发现程序中的宏后,会用宏等价的替换…

Vue 项目报错:‘$‘ is not defined ( no-undef )

错误描述 报错如上图所示,错误原因是不认识 $ 符,他是 JQuery 中得符号,我也确实引入了 JQuery: 解决办法 在 vue 项目的根目录下创建一个 .eslinttrc.js 文件,文件内容如下: module.exports {root: true…

undefined和is not defined区别

undefined定义: undefined是javascript的一种基本数据类型,变量未赋值或者函数没有返回值时返回。 xxx is not defined是一种错误类型,其完整形式是:Uncaught ReferenceError: xxx is not defined(未捕获的引用错误&a…

#define #undef等基本知识

1、预处理符号 例子&#xff1a; #include <stdio.h> #define DEBUG_PRINT printf("FILE %s line %d:" \"x%d, y%d, z%d," \__FILE__,__LINE__,x,y,z) //或者如下: //#define DEBUG_PRINT printf( "File %s line %d:…

undefined和is not defined一样吗?

https://blog.csdn.net/sheldon178/article/details/48298151/ undefined和is not defined&#xff0c;字面意思看来没什么两样&#xff0c;不都是未定义吗&#xff1f; 在JavaScript中&#xff0c;可并非如此。 undefined定义如下&#xff1a; undefined是javascript的一种…

C++中 #define 与 #undef

define 宏指令 #define 与 # include类似,它的好处呢就是速度快,使用define定义函数可以减少函数调用的额外开销 define 主要体现在2个地方 1 定义一个值 2 定义一个函数或者说功能 #include <iostream> using namespace std; // 定义一个值 #define HELLO_WORLD "…

#define #undef 使用

#define 是宏定义 #define 的用法是非常多功能的&#xff0c;它不止能实现常量宏定义&#xff0c;开关&#xff0c;还能实现函数 #undef 是取消宏定义 在undef后面要加上你要取消的宏定义 不想取消在后面可以瞎写但是不能为空 例子 #include "stdio.h"int main(…

C语言 #undef的用法

C语言中#undef的语法定义是&#xff1a;#undef 标识符&#xff0c;用来将前面定义的宏标识符取消定义。 然而&#xff0c;在实际应用中&#xff0c;#undef到底可以用来做什么&#xff1f; 整理了如下几种#undef的常见用法。 1. 防止宏定义冲突 在一个程序块中用完宏定义后&…

Perl学习-undef值和defined函数

undef值 undef是未定义的意思&#xff0c;在Perl中&#xff0c;会假设undef的变量时0或者空字符串 如果当成数字&#xff0c;就是0如果当成字符串&#xff0c;就是空字符串 当成数字 1 $n 1;2 3 while($n < 10){4 $sum $n;5 $n 2;6 }7 8 print "The tota…

吊打迅雷,最好用的BT种子下载器,下载不限速

今天小七要给大家带来的是一款安卓端BT下载器&#xff0c;用它来找片&#xff0c;下片&#xff0c;简直爽到极点&#xff0c;目前完全免费&#xff0c;无广告、无会员限制、极速下载、运行稳定支持多种格子解析、支持边下边播等等&#xff0c;拥有迅雷的所有功能&#xff0c;同…

比迅雷好用,下载速度快5倍的下载软件IDM(Internet Download Manager)

家好&#xff0c;很高兴大家阅读本文章&#xff0c;我一直在做自媒体&#xff0c;而且自媒体现在也当自己的一份工作来做了&#xff0c;那么在做自媒体的过程&#xff0c;肯定也会需要找素材&#xff0c;而在找素材的过程中需要用到下载工具&#xff0c;大家说说看现在国内&…

视频下载神器,支持 80+ 网站,比迅雷还快!

点击上方“逆锋起笔”&#xff0c;公众号回复 编程资源 领取大佬们推荐的学习资料开源最前线(ID:OpenSourceTop)编译 项目地址&#xff1a;https://github.com/soimort/you-get 今天&#xff0c;推荐一款下载神器&#xff0c;秒杀市面上你知道的所有下载工具&#xff0c;它就是…

迅雷自带的影音如何删除

1、首先下载迅雷影音&#xff1a; 2、下载之后&#xff0c;找到安装包&#xff0c;右键以压缩工具打开&#xff1a;并找到里面的XmpUninstall.exe文件---复制。 3、 复制到迅雷的安装路径下的这个路径&#xff1a;D:\Thunder Network\Thunder\Program\XMP\Program\XLGame&#…

群晖 NAS DSM 系统,只要三步使用 Docker 安装迅雷远程下载

前段时间群晖和迅雷的合作宣告终止&#xff0c;套件中移除了迅雷&#xff0c;但是说实话 DSM 自带的Download Station 实在是太慢了&#xff0c; 但是只要是 NAS是64位的处理器都可以使用 docker 套件&#xff08;好奇的同学可以了解一下 docker 的强大&#xff09;。 所以…

提高你的迅雷速度,绝对值得一看

QUOTE: 很多朋友都喜欢看电影,玩游戏.有个好的下载工具是必要的..迅雷 ,网快,bT,影音传送带 相信大家大多都使用,这四种.而相信大多数人都会使用迅雷,那是因为迅雷的速度比其它软件快的最主要的原因&#xff0c;是因为它可以通过查询候选资源来实现从多个服务器同时下载。而且…

两款清爽全能的下载神器,还不跟迅雷说拜拜?

前言 下载工具一直以来都是刚需&#xff0c;无奈近些年迅雷变得不好用后&#xff0c;广告、限速、限资源等等&#xff0c;能完美替代迅雷的免费给力的下载工具确实不好找。HTTP 类型的链接还好说&#xff0c;而种子和磁力链接这些依赖于大家做种分享的资源&#xff0c;没有迅雷…

迅雷想翻身,但区块链是好选择吗?

沉寂已久的迅雷&#xff0c;如今又有了新动作。 2月16日&#xff0c;迅雷集团旗下迅雷链推出的企业数字藏品服务平台正式上线。据悉&#xff0c;迅雷链企业数字藏品服务平台是基于迅雷链底层技术打造的&#xff0c;为企业和机构提供可信存证技术和数字藏品凭证的区块链云服务平…