静态库和动态库的使用与区别

article/2025/8/30 6:41:56

引文

库文件是计算机上的一类文件,可以理解为一种代码仓库,提供给使用者一些可以直接使用的变量、函数或类。

库文件分为两类:

  • 静态库:在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中。因此对应的链接方式称为静态链接。
  • 动态库:动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题。

1. 静态库

1.1 静态库的制作

  • 命名规则:
    • Linux:libxxx.a
      • lib: 前缀,固定
      • xxx:库的名称,自起
      • .a: 后缀,固定
    • Windows:libxxx.lib
  • 静态的制作
    • gcc 获得 .o 文件
    • 将 .o 文件打包,使用 ar(archive) 工具

命令:ar rcs libxxx.a xxx.o xxx.o

eg: arc rcs libsuanshu.a sub.o add.o mult.o div.o

1.2 静态库的使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fqCxBprS-1655380803099)(C:\Users\30863\AppData\Roaming\Typora\typora-user-images\image-20220616185553209.png)]

ydh@ubuntu:~/static_lib$ gcc main.c -o dest -I include/ -l calc -L lib/

​ 解释如下:

​ -I include/:生成目标文件所需头文件路径

​ -l calc:调用的库的名称

​ -L lib/:调用的库的路径

注:调用静态库依旧需要附带头文件,比如上述例子中的静态库calc包含了add.o、sub.o、mult.o、div.o的函数体,但是我们依旧需要头文件 head.h 来告诉我们有哪些函数。

​ head.h 的内容如下:

#ifndef _HEAD_H
#define _HEAD_H// 加法
int add(int a, int b);
// 减法
int subtract(int a, int b);
// 乘法
int multiply(int a, int b);
// 除法
double divide(int a, int b);#endif

2. 动态库

2.1 动态库的制作

  • 命名规则

    • Linux:libxxx.so
      • lib:前缀,固定
      • xxx:库的名称,自定
      • .so :后缀,固定
    • Windows:libxxx.dll
  • 动态库的制作

    • gcc 得到和位置无关的代码

      gcc -c -fpic/-fPIC a.c b.c
      
    • gcc 得到动态库

      gcc -shared a.o b.o -o libcalc.so
      

2.2 动态库的使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bDEEmyU5-1655380803100)(C:\Users\30863\AppData\Roaming\Typora\typora-user-images\image-20220616191948713.png)]

报错原因:动态库是程序运行期间动态加载到程序中的,当找不到依赖的文件时报错

此时,可以通过 ldd(list dynamic dependencies)命令查看动态库依赖关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HNgebR51-1655380803102)(C:\Users\30863\AppData\Roaming\Typora\typora-user-images\image-20220616192502944.png)]

2.3 动态库加载失败的解决方法

​既然上述问题是因为无法找到动态(共享)库的位置,那我们如何定位动态库呢?

​当系统加载可执行代码时,能够知道其所依赖的库的名字,但是还需要知道绝对路径。此时就需要系统的动态载入器来获取该绝对路径。对于elf格式的可执行程序,是由ld-linux.so来完成的,它先后搜索elf文件的DT_RPATH段–>环境变量LD_LIBRARY_PATH–>/etc/ld.so.cache文件列表–>/lib/,/usr/lib目录找到库文件后将其载入内存。

  • 方式一:直接在终端进行配置。这种配置方式只在当前终端有效。

    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:动态库路径
    

    注:$ 为取值,:为拼接,上述命令表示将原来的动态库路径加上新的动态库路径

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BcrgZutW-1655380803103)(C:\Users\30863\AppData\Roaming\Typora\typora-user-images\image-20220616193454515.png)]

  • 方式二:用户级别的,修改 .bashrc 文件,并重启该文件配置

    vim .bashrc		// 在文件的最后一行加上方式一的配置语句并退出(ESC + :wq)
    . .bashrc		// 第一个点相当于source,即source bashrc
    
  • 方式三:系统级别,修改 /etc/profile 文件,并重启该文件配置

    vim /etc/profile	// 在文件的最后一行加上方式一的配置语句并退出(ESC + :wq)
    . /etc/profile		// 第一个点相当于source,即source /etc/profile
    

3. 静态库与动态库的区别

  • 静态库优缺点

    • 优点
      • 静态库被打包到应用程序中加载速度快
      • 发布程序无需提供静态库,移植方便
    • 缺点
      • 消耗系统资源、浪费内存
      • 更新、部署、发布麻烦
  • 动态库优缺点

    • 优点
      • 可以实现进程间资源共享
      • 更新、部署、发布简单
      • 可以控制何时加载动态库
    • 缺点
      • 加载速度比静态库慢
      • 发布时需要提供依赖的动态库

说明: 参考视频https://www.nowcoder.com/study/live/504


http://chatgpt.dhexx.cn/article/8YQZdC2r.shtml

相关文章

【Linux静态库和动态库】

Linux静态库和动态库 1. 编译与ELF格式2. 库的基本概念3.静态库的制作:(假设要将a.c、b.c制作成静态库)4.静态库的常见操作5.静态库的使用6. 多个库的相互依赖举例1.(库文件制作、错误处理) 7.静态库和动态库的关系和区别8.动态库的制作软链接…

如何理解静态库与动态库

究竟什么是库: 日常生活中有很多所谓的库,比如车库啊,优衣库啊,甚至还有一库(日语)咳咳。然后对程序员来说,所谓的库,即是程序库,当一段代码十分耐用,又经过…

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;是因为它可以通过查询候选资源来实现从多个服务器同时下载。而且…