Linux系统基础-动静态库

devtools/2024/10/22 3:34:08/

个人主页:C++忠实粉丝
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C++忠实粉丝 原创

Linux系统基础-动态库和静态库

收录于专栏[Linux学习]
本专栏旨在分享学习Linux的一点学习笔记,欢迎大家在评论区交流讨论💌

目录

1. 动静态库的概念

2. 生成静态库

3. 生成动态库

4. 使用静态库

5. 使用动态库

6. 使用外部库 

7.  动态库加载

8. 总结

动态库与静态库的优缺点总结: 

1. 静态库

2. 动态库 

动态库和静态库使用场景总结: 

1. 静态库的使用场景

2. 动态库的使用场景


1. 动静态库的概念

静态库(.a) : 程序在编译链接的时候把库的代码链接到可执行文件中, 程序运行的时候将不在需要静态库

动态库(.so) : 程序在运行的时候才去链接动态库的代码, 多个程序共享使用库的代码.

我们可以使用ldd查看一个程序所连接的库:

可以看到我们简单一个C语言程序连接了三个库 

补充:

1. 一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表, 而不是外部函数所在目标文件的整个机械码

2. 在可执行文件开始运动以前, 外部函数的机械码由操作系统从磁盘上的动态库中复制到内存中, 这个过程称为动态链接 (dynamic linking)

3. 动态库可以在多个程序间共享, 所以动态链接使得可执行文件更小, 节省了磁盘空间, 操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用, 节省了内存和磁盘空间 

2. 生成静态库

测试程序: 

add.h
#ifndef __ADD_H__
#define __ADD_H__
int add(int a, int b);
#endif // __ADD_H__sub.h
#ifndef __SUB_H__
#define __SUB_H__
int sub(int a, int b);
#endif // __SUB_H__add.c
#include "add.h"
int add(int a, int b)
{return a + b;
}sub.c
#include "add.h"
int sub(int a, int b)
{return a - b;
}main.c
#include <stdio.h>
#include "add.h"
#include "sub.h"int main()
{int a = 10;int b = 20;printf("add(%d, %d)=%d\n", a, b, add(a, b));a = 100;b = 20;printf("sub(%d,%d)=%d\n", a, b, sub(a, b));return 0;
}

 直接运行结果:

生成静态库:

所谓的库文件, 本质, 就是把.o打包

ar是gnu归档工具,rc表示(replace and create)

查看静态库中的目录列表, t:列出静态库中的文件 v:verbose 详细信息 

 

3. 生成动态库

shared: 表示生成共享库格式

fPIC:产生位置无关码(position independent code)

库名规则:libxxx.so

4. 使用静态库

-L 指定库路径 -l 指定库名

测试目标文件生成后,静态库删掉,程序照样可以运行 

库搜索路径 :

从左到右搜索-L指定的目录.

由环境变量指定的目录 (LIBRARY_PATH)

由系统指定的目录

1. /usr/lib

2. /usr/lical/lib

5. 使用动态库

编译选项:

l:链接动态库,只要库名即可(去掉lib以及版本号)

L:链接库所在的路径

6. 使用外部库 

系统中其实有很多库,它们通常由一组互相关联的用来完成某项常见工作的函数构成。比如用来处理屏幕显示情况的函数(ncurses库) 

下载ncurses库

sudo apt update
sudo apt install libncurses5-dev libncursesw5-dev

 示例代码:

#include <math.h>
#include <stdio.h>
int main(void)
{double x = pow(2.0, 3.0);printf("The cubed is %f\n", x);return 0;
}

-lm表示要链接libm.so或者libm.a库文件 

库文件名称和引入库的名称

如:libc.so -> c库,去掉前缀lib,去掉后缀.so,.a 

7.  动态库加载

 

动态库在加载之后, 要映射在当前进程的堆栈之间的共享区

动态库也叫做共享库!!

8. 总结

动态库要在程序运行的时候, 要找到动态库加载并运行!

静态库为什么没有这个问题? 因为静态库编译期间已经将库中的代码拷贝到我们的可执行文件内部了, 加载和库就没有关系了~

动态库 VS 静态库

默认连接的是动态库, 如果你没有使用-static, 并且只提供.a, 只能静态链接当前的.a库, 其他库正常动态链接

-static的意义是什么呢? 必须强制将我们的程序静态连接, 这就要求我们来凝结的任何库都必须提供对应的静态库版本~~

动态库与静态库的优缺点总结: 

1. 静态库

优先: 

1. 执行效率高 : 静态库在编译时直接连接到可执行文件中, 因此程序在运行时不需要加载库文件, 通常会有更快的启动时间和执行效率.

2. 部署简单: 将所有代码打包为一个可执行文件, 不需要在运行时依赖外部库, 简化了部署过程

3. 版本控制: 不受外部库版本的影响, 避免了库更新造成的问题

缺点: 

1. 文件大小大: (上文也有所展示)因为将库的代码复制到每个可执行文件中, 导致生成的可执行文件体积较大, 占用很大内存

2. 更新困难 : 如果需要修复静态库中的bug或添加新特性, 需要重新编译有所依赖该库的可执行文件

3. 资源浪费 : 如果多个程序使用相同的静态库, 它们会各自包含一份库的副本, 占用更多的磁盘和内存空间

2. 动态库 

优先: 

1. 节省内存 : 多个进程可以共享同一个动态库的副本, 减少了内存使用

2. 更新方便 : 只需要替换动态库文件, 无需重新编译依赖该库的应用程序, 便于维护和更新

3. 启动速度快 : 可以在程序运行时按需加载库, 减少初始加载时间

缺点: 

1. 运行时依赖 : 程序运行时需要依赖动态库, 缺失动态库会导致程序无法运行.

2. 调试复杂 : 由于动态连接, 调试过程可能会更加复杂, 特别是在库的版本不兼容时.

3. 加载开销 : 动态库在运行时需要加载, 可能会导致启动时间延长

动态库和静态库使用场景总结: 

1. 静态库的使用场景

1. 小型项目 : 对于小型项目或工具, 使用静态库可以简化构建和部署流程.

2. 不频繁更新的库 : 当库功能稳定且不需要频繁更新时, 使用静态库是合法的

3. 性能要求高的应用 : 在对性能有严格要求的场景下, 静态库可能更具有优势

2. 动态库的使用场景

1.大型应用程序 : 在大型系统中, 使用动态库可以减少内存占用, 特别是当多个程序共享一个库时

2. 频繁更新的库 : 当库需要频繁更新, 且不希望重新编译所有应用时, 动态库是更好的选择.

3. 插件系统 : 在需要实现插件架构的应用中, 动态库允许程序在运行时加载和卸载插件

4. 跨平台开发 : 动态库在不同平台上的使用可以更灵活, 特别是在使用不同版本的依赖时.

 


http://www.ppmy.cn/devtools/127721.html

相关文章

Vue 组件 view-shadcn-ui 2024.1.1 发布

Vue 组件 view-shadcn-ui 2024.1.1 发布 View Shadcn UI 是一个基于 Shadcn UI 和 Tailwind CSS 构建的组件库。 推荐一套为 Java 开发人员提供方便易用的 SDK 来与目前提供服务的的 Open AI 进行交互组件&#xff1a;https://github.com/devlive-community/openai-java-sdk 推…

面试官:`interrupted()` 和 `isInterrupted()` 你真的用懂了吗?

感谢Java面试教程的 Java面试题&#xff1a;interrupted和isInterrupted方法的区别 在Java中&#xff0c;interrupted() 和 isInterrupted() 是用于检查线程中断状态的方法&#xff0c;但它们之间有一些关键的区别。 方法类型&#xff1a; interrupted() 是一个静态方法&…

深度学习--CNN实现猫狗识别二分类(附带下载链接, 长期有效)

1. 代码实现(包含流程解释) 样本量: 8005 # # 1.导入数据集(加载图片)数据预处理# 进行图像增强, 通过对图像的旋转 ,缩放,剪切变换, 翻转, 平移等一系列操作来生成新样本, 进而增加样本容量, # 同时对图片数值进行归一化[0:1] from tensorflow.keras.preprocessing.image …

2018年计算机网络408真题解析

第一题&#xff1a; 解析&#xff1a;TCP/IP体系结构应用层常用协议及其相应的运输层协议 TCP协议是面向连接可靠数据传输服务&#xff0c;UDP无连接不可靠的数据传输服务&#xff0c;IP无连接不可靠的数据连接服务。 FTP协议&#xff0c;SMTP协议和HTTP协议使用TCP协议提供的面…

Axure大屏可视化模板:打造跨领域数据分析平台的原型设计案例

数据可视化已成为各行各业提升管理效率、优化决策过程的重要手段。Axure作为一款强大的原型设计工具&#xff0c;其大屏可视化模板在农业、园区、城市、企业数据可视化、医疗等多个领域得到了广泛应用。本文将通过几个具体案例&#xff0c;展示Axure大屏可视化模板在不同领域中…

【CHI】CHI协议自问自答

学习CHI有一段时间了&#xff0c;如今回过头来&#xff0c;再读协议&#xff0c;一些问题做个记录。如果有错误的地方&#xff0c;欢迎指正。如果有其他的问题&#xff0c;也欢迎留言讨论。 spec&#xff1a; IHI0050F_amba_chi_architecture_spec 【持续更新ing】 目录 1. …

基于机器学习的二手车价格因素识别与预测

1.项目背景 随着二手车市场的快速发展&#xff0c;消费者对二手车的需求逐渐增加&#xff0c;然而&#xff0c;由于二手车的定价涉及多种复杂因素&#xff0c;不同条件下的车辆价值差异较大&#xff0c;如何精准地评估二手车的市场价值成为了一个亟待解决的问题。本项目通过数…

《使用Gin框架构建分布式应用》阅读笔记:p52-p76

《用Gin框架构建分布式应用》学习第4天&#xff0c;p32-p76总结&#xff0c;总计25页。 一、技术总结 1.Go知识点 (1)iouti 书上使用ioutil包读取JSON文件&#xff0c;但是从go 1.16 开始&#xff0c;不再推荐使用ioutil&#xff0c;应该使用os 包。 (2)json.Unmarshal() …