Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >静态库与动态库的那些事

静态库与动态库的那些事

原创
作者头像
yzh
修改于 2020-08-10 02:41:49
修改于 2020-08-10 02:41:49
1.7K00
代码可运行
举报
文章被收录于专栏:YZh学习记录YZh学习记录
运行总次数:0
代码可运行

【根据近期理解,进行整理,如果错误,欢迎指正】

编译流程:

分为四个步骤:预处理 编译 汇编 链接

(1)预处理(Preprocessing)

实现功能:

完成宏替换、文件引入、以及去除空行、注释等,为下一步的编译做准备。也就是对各种预处理命令进行处理,包括文件的包含、宏定义的扩展、条件编译的选择等。

命令:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ gcc -E test.c -o test.i      #test.c为源文件

选项-E让gcc在预处理结束后停止编译,“test.i”文件为预处理后输出文件。-o 指定输出文件

预处理后文件会变大很多。

(2) 编译(Compilation)

实现功能:

将预处理后的代码变成汇编代码。在这个阶段中,首先要检查代码的规范性、是否有语法错误等,以确定代码实际要做的工作,在检查无误后,再把代码翻译成汇编语言。 2.编译程序执行时,先分析,后综合。分析,就是指词法分析、语法分析、语义分析和中间代码生成。综合,就是指代码优化和代码生成。 3.大多数的编译程序直接产生机器语言的目标代码,形成可执行的目标文件,也有的是先产生汇编语言一级的符号代码文件,再调用汇编程序进行翻译和加工处理,最后产生可执行的机器语言目标文件。

命令:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ gcc -S test.i -o test.s

选项-S让gcc在编译结束后停止编译过程,“test.s”文件为编译后生成的汇编代码。

(3)汇编(Assemble)

实现功能:

汇编就是把编译阶段生成的“.s”文件转成二进制目标代码,也就是机器代码(01序列)。

命令:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ gcc -c test.s -o test.o

选项-c让gcc在汇编结束后停止编译过程,“test.o”文件为汇编后生成的机器码目标文件。

(4)链接(Linking)

实现功能:

链接就是将多个目标文件以及所需的库文件链接生成可执行目标文件的过程。

命令:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ gcc test.o -o test

-o本质上是一个重命名选项。不适用-o选项时,默认生成的是a.out文件。这里生成的是可执行文件test。

以上是编译实现的四个步骤过程。

运行

执行可执行程序

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ ./test

库是一组目标文件的包,就是一些最常用的代码编译成目标文件后打包存放。

静态库

静态库(.a 、.lib)

1.静态库是在汇编过程生成的,加载静态态库是在链接过程之前

2.静态库实际就是一些目标文件(一般以.o结尾)的集合,静态库一般以.a结尾,只用于生成可执行文件阶段。 3.在链接步骤中,链接器将从库文件取得所需代码,复制到生成的可执行文件中。这种库成为静态库。

可执行文件中包含了库代码的一份完整拷贝,在编译过程中被载入程序中。

缺点就是多次使用就会有多份冗余拷贝,并且对程序的更新、部署和发布会带来麻烦,如果静态库有更新,那么所有使用它的程序都需要重新编译、发布。

生成静态库的过程

1. 将源文件生成 目标文件(完成到汇编的过程)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ gcc -c test.c -o test.o

2. 使用ar命令将test.o打包成libtest.a静态库

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ ar rcs libtest.a test.o

3. 查看静态库的具体内容, 静态库其实就是目标文件的集合

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ ar t libtest.a 
test.o

动态库

动态库(.so 、.dll )

1.动态库是在汇编过程生成的,加载动态库是在程序运行过程中

2.动态库在链接阶段没有被复制到程序中,而是在程序运行时由系统动态加载到内存中供程序调用。 3.系统只需要载入一次动态库,不同的程序可以得到内存中相同动态库的副本,因此节省了很多内存。

4.程序运行可执行文件加载动态库,需要动态的设置动态库地址,才能运行。即将动态库放置在可执行文件同级目录下

这里和静态库有着很大的不同之处

生成动态库的过程:

1. 将源文件生成 目标文件(完成到汇编的过程)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ gcc -c test.c -o test.o

使用-share和-fPIC参数生成动态库。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ gcc -shared -fPIC -o libtest.so test.o

根据前面对动态库,静态库的理解,下面进一步理解动态链接库,静态链接库

根据上面的理解,以为lib为静态库,dll为动态库,这理解并不错,但不全面。

lib分两种

(1) lib包含所有内容的静态库,应用程序用它即可,这是我上面理解的一种

(2) lib只包含头部信息,为了配合dll使用,dll包含函数内容,此时,可以观察出lib比dll小很多:

比如:opencv中的这两个文件。lib 只是一些函数入口,dll包含函数内容。

因此可以总结为,共有两种库:

动态链接库dynamic link library

一种是LIB包含了函数所在的DLL文件和文件中函数位置的信息(入口),代码由运行时加载在进程空间中的DLL提供,称为动态链接库dynamic link library。

静态链接库static link library

一种是LIB包含函数代码本身,在编译时直接将代码加入程序当中,称为静态链接库static link library。

静态链接库实际上是一个目标文件的集合,其中的每个文件含有库中的一个或者一组相关函数的代码。

共有两种链接方式:

动态链接使用动态链接库,允许可执行模块(.dll文件或.exe文件)仅包含在运行时定位DLL函数的可执行代码所需的信息。

静态链接使用静态链接库,链接器从静态链接库LIB获取所有被引用函数,并将库同代码一起放到可执行文件中。

关于lib和dll的区别如下:

(1)lib是编译时用到的,dll是运行时用到的。如果要完成源代码的编译,只需要lib;如果要使动态链接的程序运行起来,只需要dll。

(2) 如果有dll文件,那么lib一般是一些索引信息,记录了dll中函数的入口和位置,dll中是函数的具体内容(动态链接库);

如果只有lib文件,那么这个lib文件 是静态编译出来的,索引和实现都在其中(静态链接库)。使用静态编译的lib文件,在运行程序时不需要再挂动态库,缺点是导致应用程序比较大,而且失去了动态库的灵活 性,发布新版本时要发布新的应用程序才行。

(3)动态链接的情况下,有两个文件:一个是LIB文件,一个是DLL文件。LIB包含被DLL导出的 函数名称和位置,DLL包含实际的函数和数据,应用程序使用LIB文件链接到DLL文件。在应用程序的可执行文件中,存放的不是被调用的函数代码,而是 DLL中相应函数代码的地址,从而节省了内存资源。DLL和LIB文件必须随应用程序一起发行,否则应用程序会产生错误。

使用lib需注意两个文件:

(1).h头文件,包含lib中说明输出的类或符号原型或数据结构。应用程序调用lib时,需要将该文件包含入应用程序的源文件中。

(2).LIB文件,目标文件的集合。

使用dll需注意三个文件:

(1).h头文件,包含dll中说明输出的类或符号原型或数据结构的.h文件。应用程序调用dll时,需要将该文件包含入应用程序的源文件中。

(2).LIB文件,是dll在编译、链接成功之后生成的文件,作用是当其他应用程序调用dll时,需要将该文件引入应用程序,否则产生错误。

(3).dll文件,真正的可执行文件,开发成功后的应用程序在发布时,只需要有.exe文件和.dll文件,并不需要.lib文件和.h头文件。

参考链接:

https://www.cnblogs.com/405845829qq/p/4108450.html

https://blog.csdn.net/roy_xing/article/details/90372477?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【Linux】想学习Linux不看这一篇你就慢了-->工具篇(二)gcc/g++、动静态链接(动静态库)
静态库: libXXXXXX.a:lib是前缀,.a是静态库的后缀,去掉前后缀就是库的名称
HABuo
2025/05/27
460
【Linux】想学习Linux不看这一篇你就慢了-->工具篇(二)gcc/g++、动静态链接(动静态库)
【库函数】Linux下动态库.so和静态库.a的生成和使用
我在路径/root/host/my_program/asoc/include下创建四个文件
SarPro
2024/04/25
2.2K0
【库函数】Linux下动态库.so和静态库.a的生成和使用
C语言 | 什么是静态链接库和动态链接库?
今天分享的是静态链接库和动态链接库的相关知识,并且自己动手写一个简单的静态函数库和动态函数库,来体验这个流程。
飞哥
2020/08/11
4.9K0
C语言 | 什么是静态链接库和动态链接库?
Linux:基础IO(三.软硬链接、动态库和静态库、动精态库的制作和加载)
上次介绍了基础IO(二):Linux:基础IO(二.缓冲区、模拟一下缓冲区、详细讲解文件系统)
是Nero哦
2024/07/01
3190
Linux:基础IO(三.软硬链接、动态库和静态库、动精态库的制作和加载)
C++基础 静态库与动态库
如果在程序中使用静态链接库,那么链接器在链接的过程中会将.obj文件和.lib文件组织成可执行exe文件,也就是将.lib中的代码链接到可执行文件中,因此生成的exe文件比较大。 程序运行时,将全部数据加载到内存。如果程序体积较大,功能较为复杂,那么加载到内存中的时间就会比较长,最直接的一个例子就是双击打开一个软件,要很久才能看到界面。这是静态链接库的一个弊端。 但程序在发行时不需要提供库文件。
xxpcb
2020/08/04
1.5K0
【一站式解惑】Linux中.a、.so和.o文件以及-I,-L,LIBRARY_PATH,LD_LIBRARY_PATH等
在说明Linux的.a、.so和.o文件关系之前,先来看看windows下obj,lib,dll,exe的关系。
自学气象人
2023/01/13
5.8K0
c++动态库和静态库的区别_静态库里面包含动态库
C++静态库与动态库
全栈程序员站长
2022/11/11
2.1K0
动态库和静态库的特性
库是共享程序代码的方式,一般分为静态库(static libraries)、动态库(dynamically loaded libraries)和共享库(shared libraries)。
李小白是一只喵
2020/04/23
1.9K0
C语言---静态库VS动态库
在编程的过程中,使用已经封装好的库函数是十分方便的,也是十分高效的,因此会使用函数库是很重要的。在C语言中,函数库文件分为两种类型,一种是静态库(库程序是直接注入目标程序的,不分彼此,库文件通常以.a结尾),另一种是动态库(库程序是在运行目标程序时(中)加载的,库文件通常以.so结尾),下面我们就探索一下这两种库文件的特点和使用方式吧!
HeaiKun
2020/07/07
9.1K0
linux 动态库 静态库_静态库里面包含动态库
那么这三个时间有什么作用呢? 我们在使用自动化构建工具Makefile时,如果连续make会发现:
全栈程序员站长
2022/11/10
7.7K0
linux 动态库 静态库_静态库里面包含动态库
一文带你了解静态库和动态库
我们在编写代码的时候经常用到已有的接口,他们是以库的形式提供给我们使用的,而常见形式有两种,一种常以.a为后缀,为静态库;另一种以.so为后缀,为动态库。那么这两种库有什么区别呢?
编程珠玑
2019/07/12
1.1K0
库的概念:动态库与静态库
库是一组封装好的函数或方法,它们可以被多个程序复用,从而避免重复编写相同功能的代码。例如,标准的数学函数库、字符串操作库都属于常用的库。
DevKevin
2025/01/03
3450
C++程序编译之谜(二)——隐藏源码,动态和静态链接库的秘密
前面我们提到了如果我们不希望把我们的源码提供出来,但是又想提供这个接口给调用者调用,那么这个该怎么做呢?
一点sir
2024/01/10
3050
深入浅出链接库 | 静态库与动态库
不管是在 Windows 下开发,还是在 Linux 下开发,我们都会经常性的使用一些库文件,这些库文件的特点就是,我们可以看到接口的原型并通过这些接口来调用这个函数的功能,但是我们无法查看这个功能的实现。这就是库文件,功能提供者把头文件和库文件发布给我们,我们便可以根据头文件中的接口去调用库文件中实现的功能,并且对我们隐藏了功能实现的源码和细节。其实,链接库(动态库和静态库)并没有什么神秘的,本文就带你一起解开链接库的神秘面纱,让大家自己也可以动手制作动态库与静态库。
mindtechnist
2024/08/08
9080
深入浅出链接库 | 静态库与动态库
【Linux系统编程】Linux下的编译器——gcc/g++的使用 及 动态库和静态库的认识
gcc (GNU Compiler Collection) 和 g++ 是 Linux 系统上最常用的编译器。它们是 GNU 组织开发的一套开源编译器工具集。
YIN_尹
2024/01/23
2.6K0
【Linux系统编程】Linux下的编译器——gcc/g++的使用 及 动态库和静态库的认识
Linux中C/C++程序编译过程与动静态链接库概述
ldd 是 Linux 中的一个命令,用于显示一个可执行文件或共享库所依赖的共享库(动态链接库)。这个命令可以帮助开发者和系统管理员检查程序的动态链接依赖关系,确保所有必要的库都能找到,并且程序能够正常运行。
Srlua
2024/10/27
3650
Linux中C/C++程序编译过程与动静态链接库概述
【Linux】动静态库(超详细)
💢 由于CentOS 8系统2021年12月31日已停止维护服务,CentOS 7系统将于2024年06月30日停止维护服务。CentOS官方不再提供CentOS 9及后续版本,不再支持新的软件和补丁更新。CentOS用户现有业务随时面临宕机和安全风险,并无法确保及时恢复。
IsLand1314
2024/11/19
1460
【Linux】动静态库(超详细)
程序生成之编译、链接、加载浅析
剑影啸清寒
2018/01/02
1.3K0
程序生成之编译、链接、加载浅析
静态链接库和动态链接库的区别
Linux下得库有动态与静态两种,动态通常用.so为后缀,静态用.a为后缀。面对比一下两者:
狼啸风云
2019/11/03
8.7K0
【Linux】掌握库的艺术:我的动静态库封装之旅
在计算机编程中,库(Library)是一个预先编写的代码集合,包含了可以被其他程序调用的函数、类、变量和资源。库的主要目的是为了简化编程过程,提供常用功能的实现,促进代码重用,从而减少开发时间和提高软件的可靠性。
Yui_
2024/11/19
1240
【Linux】掌握库的艺术:我的动静态库封装之旅
推荐阅读
相关推荐
【Linux】想学习Linux不看这一篇你就慢了-->工具篇(二)gcc/g++、动静态链接(动静态库)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验