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

Linux|静态库 共享库

认识静态库和共享库,首先要了解什么是库:

库是一组预先编译好的方法的集合,在Linux系统中,存储库的位置一般在/lib 和 /usr/lib (64位系统:/usr/lib64),库的头文件放在/usr/include。

库分为静态库(后缀名.a)和共享库(后缀名.so)

一、静态库

1.生成

(1)先将需要生成库文件的所有.c文件编译成.o文件;

         gcc -c xxx.c xxx.c

(2)使用ar命令创建静态库

        ar crv libxxx.a xxxx.o xxx.o

        参数:

        c:创建库 r:将方法添加到库中 v:显示过程

2.使用静态库

 gcc -o main main.c   -L. -lxxx

 -L:指定库的存储位置

-l:指定库的名称(不需要前面的lib和扩展名.a)
例如:gcc -o main main.c -L. -lfoo

 3.静态库的缺点

如果同时运行许多应用程序并且它们都使用来自同一个函数库的函数时,内存中就会有同一函数的多个副本.而且在程序文件自身中也有多份同样的副本,这将消耗大量宝贵的内存和磁盘空间;

二、共享库

1.生成

(1)将所有的.c文件编译成目标文件.o

(2)将所有目标文件打包生成共享库:

gcc -shared -fPIC -o libxxx.so xxx.o xxx.o

2.使用

共享库的使用: gcc -o main main.c -L路径 -l库名

*注意:共享库必须要放到标准路径下: sudo mv libxxx.so /usr/lib

否则是运行不了的,要把共享库放到标准路径下

补充一个命令: 查看使用了哪些共享库:ldd main

通过ldd main发现没有找到libfoo.so

移动到标准路径下:

这样就可以运行了。(但一般不要随意篡改系统的lib文件,建议简单运行了解原理后删除自己增加的共享库文件)

 三、静态库与共享库的区别

举例来说,某个共享库如果10个应用程序共享,那么磁盘上只有一份共享的库文件,而且运行加载时在内存中只加载了标记了的这一份库文件; 而静态库,就是这10个应用程序都包含了这个库文件,那么10份的库文件都放在磁盘上了(占用磁盘空间),而且运行加载的时候占用内存空间(10份库文件都要加载);

总结一下二者的优缺点:

静态库:
优点:

易于使用和部署:在链接阶段,静态库的代码会被完整地复制到可执行文件中。这意味着在部署时,只需要将可执行文件及其依赖的其他资源(如配置文件、数据文件等)一起发布即可,无需额外考虑库文件的安装和配置,用户拿到可执行文件就能直接运行。在可执行程序中已经具备了所有执行程序所需要的任何东西,在执行的时候运行速度快。
稳定性高:由于静态库的代码已经被嵌入到可执行文件中,所以它不会受到外部库版本变化的影响。只要可执行文件本身不被修改,其运行结果就是确定的,不会因为系统中安装的库文件被更新或替换而出现意外的行为。
安全性较高:静态库的代码在编译时就已经固定到可执行文件中,相对来说更难被外部恶意程序篡改或替换。因为要修改静态库中的代码,就需要直接修改可执行文件,而可执行文件通常有一定的保护机制,这增加了攻击者的难度。
缺点:
可执行文件体积大:每个使用静态库的可执行文件都会包含一份静态库的完整副本。如果多个可执行文件都依赖于同一个静态库,那么这个库的代码就会在这些文件中重复出现,导致可执行文件的体积增大。这不仅会占用更多的磁盘空间,而且在网络传输和加载到内存时也会花费更多的时间。
更新和维护困难:当静态库的代码发生更新时,所有依赖该静态库的项目都需要重新编译和链接。如果项目规模较大或者有多个项目依赖同一个静态库,那么这个更新过程可能会非常繁琐,而且容易出现遗漏,导致部分项目没有及时更新到最新的库版本。


共享库:
优点:
节省磁盘空间和内存:
多个可执行文件可以共享同一个共享库的代码。在磁盘上,共享库只需要存储一份,多个可执行文件在运行时都可以链接到这个共享库上,而不是像静态库那样每个可执行文件都包含一份完整的库代码。这样可以大大节省磁盘空间。在内存中,当多个进程同时使用同一个共享库时,操作系统只需要将共享库的代码加载到内存一次,多个进程可以共享这段内存空间,从而节省了内存资源。
更新和维护方便:当共享库的代码发生更新时,只需要替换系统中的共享库文件即可,不需要重新编译和链接依赖该共享库的所有可执行文件。只要新的共享库保持了与旧版本的接口兼容性,那么依赖它的可执行文件就可以直接使用新的共享库,无需进行任何修改。
缺点:
依赖关系复杂:
共享库的使用引入了额外的依赖关系。一个可执行文件依赖的共享库可能又依赖其他的共享库,形成复杂的依赖链。在部署和运行时,需要确保所有依赖的共享库都能被正确找到和加载,否则可能会导致程序运行错误。
版本兼容性问题:虽然共享库的更新方便,但如果新的共享库版本与旧版本的接口不兼容,就可能导致依赖旧版本的可执行文件无法正常运行。这就需要在更新共享库时非常小心,确保新版本与旧版本的兼容性,或者提供适当的版本管理机制,让不同版本的共享库能够共存,以满足不同程序的需求。
安全性相对较低:由于共享库是独立于可执行文件存在的,并且多个程序共享使用,所以它更容易成为攻击者的目标。如果共享库被恶意篡改或植入了恶意代码,那么所有依赖该共享库的程序都可能受到影响。

性能损耗:因为把链接推迟到了程序运行时,所以每次执行程序都需要进行链接,所以性能会有一定损失。

over!

相关文章:

  • redis十大应用数据类型具体使用及其应用
  • Go语言不定长参数使用详解
  • 【蓝桥杯】第十三届C++B组省赛
  • 删除排序链表中的重复元素(js实现,LeetCode:83)
  • 解决远程卡在下载vscode-server的问题,一键安装脚本
  • 网站搭建(node.js安装后hexo无法安装的修复步骤)
  • C语言之数据结构:链表
  • 嵌入式硬件篇---龙芯UART通信
  • vscode使用ssh同时连接主机CentOS:user和ubuntu20.04:docker
  • MATLAB 2024b深度学习新特性全面解析与DeepSeek大模型集成开发
  • vue:组件的使用
  • Qt 实操记录:打造自己的“ QQ 音乐播放器”
  • Pycharm接入DeepSeek,提升自动化脚本的写作效率
  • 【css酷炫效果】纯CSS实现故障文字特效
  • 设计模式(创建型)-单例模式
  • 【前端面试题】闭包和其应用
  • 安卓apk加固后,Android11+无法安装
  • 在NET6项目中报错,未能在命名空间System.Data.SqlClient中找到类型名SqlCommand,解决办法
  • 一次由IDEA配置引发的Redis连接问题
  • 区块链赋能:用Python开发去中心化投票系统
  • 王毅:时代不容倒退,公道自在人心
  • 澎湃读报丨解放日报9个版聚焦:上海,加快建成具有全球影响力的科技创新高地
  • 对话|贝聿铭设计的不只是建筑,更是生活空间
  • 太好玩了!坐进大卫·霍克尼的敞篷车进入他画笔下的四季
  • 上海通报5起违反中央八项规定精神问题
  • 物业也能成为居家养老“服务员”,上海多区将开展“物业+养老”试点