【Linux】16. 动静态库

news2024/11/15 5:39:14

1. 库概念的引出

在这里插入图片描述
在这里插入图片描述
但是如果只是单纯的将多个.o文件提供给使用者,那么如果.o文件过多链接就会变得非常复杂,于是我们考虑将所有的.o文件打包给使用者提供一个库文件即可。
库的本质就是.o文件的集合

2. 动静态库概念

在之前的学习过程中我们认识到动静态链接会生成对应的库类型
静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库
动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。

3. 静态库

3.1 静态库的生成

在这里插入图片描述
在这里插入图片描述

我们执行如下命令:

[hx@hx dynamic_static_lib]$ tar czf mylib.tgz mylib
[hx@hx dynamic_static_lib]$ ll
total 56
-rw-rw-r-- 1 hx hx 3296 Jun 22 13:03 libmymath.a
-rw-rw-r-- 1 hx hx  231 Jun 20 19:25 main.c
-rw-rw-r-- 1 hx hx  303 Jun 22 13:38 makefile
-rw-rw-r-- 1 hx hx  120 Jun 20 19:15 my_add.c
-rw-rw-r-- 1 hx hx   67 Jun 20 19:16 my_add.h
-rw-rw-r-- 1 hx hx 1544 Jun 22 13:03 my_add.o
drwxrwxr-x 4 hx hx 4096 Jun 22 13:39 mylib
-rw-rw-r-- 1 hx hx  940 Jun 22 14:46 mylib.tgz
-rwxrwxr-x 1 hx hx 8568 Jun 20 19:38 mymath
-rw-rw-r-- 1 hx hx  117 Jun 20 19:17 my_sub.c
-rw-rw-r-- 1 hx hx   64 Jun 20 19:17 my_sub.h
-rw-rw-r-- 1 hx hx 1544 Jun 22 13:03 my_sub.o

将库文件和头文件打包压缩,形成.tgz文件将其上传到yum资源当中或者发布到XXX网站上
使用者就可以通过访问网站/资源的方式来获取到

3.2 静态库的使用

3.2.1 指定当前路径下编译使用

在这里插入图片描述
那为啥不需要告诉编译器头文件需要链接哪个头文件,而是只是告诉编译器头文件路径即可,因为我们在代码编译时(#include “my_add.h”)
已经告诉编译器了我们所要包含的头文件是啥了
在这里插入图片描述
所以如果要链接第三方库,就一定要指明库的名称
那为啥编写C语言/C++时,我们不需要指明库名称呢? – 因为gcc(编译C语言) g++(编译C++) 编译器本身就知道链接库的名称
在这里插入图片描述

3.2.2 添加到系统路径下使用(安装)

在这里插入图片描述
这种方式其本质也叫做库的安装
软件的安装其实也是一个道理,将软件添加到对应的系统路径下
在学习的过程中不太推荐,因为目前编写的大多是测试/小程序没有经过严格的测试和发布这些流程,所以不推荐将自己写的库直接安装到系统当中

4. 动态库

4.1 动态库的生成

在这里插入图片描述

4.2 动态库的使用

在这里插入图片描述
那么如何告诉OS自定义库的位置呢?

  1. 拷贝.so文件到系统共享库路径下, 一般指/usr/lib (安装 --> 现阶段不太推荐将自己写的安装到系统共享库中 )
  2. 添加到环境变量LD_LIBRARY_PATH当中(一次性)
    系统在搜索库文件路径时,除了在系统默认的库路径下查找之外还会在环境变量LD_LIBRARY_PATH当中查找
    在这里插入图片描述
    但是当我们将机器退出后,再运行又无法找到,原因是因为自定义的环境变量只在本次登录有效
  3. 配置/etc/ld.so.conf.d/,ldconfig更新
    在这里插入图片描述
  4. 给运行程序建立软链接
    在这里插入图片描述

5. 使用外部库

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

#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;
}
gcc -Wall calc.c -o calc -lm

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

6. 动态库的加载

静态库是不会加载到内存当中的,在链接时静态库就是将其方法拷贝到对应的调用处,当后续程序在运行的过程当中就不再依赖静态库。
但是如果静态库当中的方法被不同的文件调用,会在内存中出现重复的代码(浪费空间)
链接时发生的拷贝会拷贝到虚拟地址空间的代码区当中,(程序在未编译形成之前,编译器也会按照虚拟地址空间的方式划分区域,对应的拷贝就是存放到代码区),所以未来这部分代码必须通过相对确定的地址位置来进行访问
在这里插入图片描述

动态库命令的理解:

  1. 为啥形成.o文件要带-fPIC选项 是因为会生成位置无关码,可以理解为形成的函数地址不是绝对编址,只是相对编址的方案
  2. -shell 打包形成动态库格式 ,方便操作系统以库方式加载

当内存中存在100个可执行程序,都使用的是同一个库的话,那么只需要将这一个库加载到内存当中即可(节约内存空间)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/677577.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

免费:5000个高清视频素材 (个人免费版权,含9个利基)

免费&#xff1a;5000个高清视频素材 (个人免费版权&#xff0c;含9个利基) 嘿&#xff01;你喜欢制作视频吗&#xff1f;总是在寻找一些酷炫的素材&#xff0c;但又担心会侵犯版权吗&#xff1f;别担心&#xff0c;我有一个超级好消息要告诉你&#xff01;现在&#xff0c;我…

代码随想录算法训练营第39天 | 62.不同路径 + 63.不同路径 II

今日任务 目录 62.不同路径 - Medium 63.不同路径 II - Medium 62.不同路径 - Medium 题目链接&#xff1a;力扣-62. 不同路径 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器…

【数据结构】排序

插入排序 把当前遍历到的元素前的元素序列是排好序的,把当前元素放到前边的序列中进行排序。 直接插入排序 不带哨兵 void InsertSort(int A[],int n) { int i,j,temp; for(i1;i<n;i) if(A[i]<A[i-1]) { tempA[i]; for(ji-1;j>0 && A[j]>temp;--j) A[j…

深入理解深度学习——BERT派生模型:参数共享ALBERT

分类目录&#xff1a;《深入理解深度学习》总目录 预训练语言模型的一个趋势是使用更大的模型配合更多的数据&#xff0c;以达到“大力出奇迹”的效果。随着模型规模的持续增大&#xff0c;单块GPU已经无法容纳整个预训练语言模型。为了解决这个问题&#xff0c;谷歌提出了ALBE…

深度学习训练营之文本分类识别

深度学习训练营之文本分类识别 原文链接环境介绍前置工作设置环境设置GPU加载数据 构建词典生成数据批次和迭代器模型定义定义实例 定义训练函数和评估函数模型训练模型评估 原文链接 &#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f366; 参考…

面具下的flag

打开文件是你的名字动漫的一张图片 用010打开文件&#xff0c;比较可疑的有三处 首先文件头是正确的&#xff0c;只是这边显示的Exif&#xff0c;之前没有特别注意jpg文件有这个头 其次是文件中包含两处flag信息&#xff0c;一个是类似隐藏的文件&#xff0c;一个疑似是第二段f…

Mysql高级查询语句

数据库是用来存储数据&#xff0c;更新&#xff0c;查询数据的工具&#xff0c;而查询数据是一个数据库最为核心的功能&#xff0c;数据库是用来承载信息&#xff0c;而信息是用来分析和查看的。所以掌握更为精细化的查询方式是很有必要的。本文将围绕数据的高级查询语句展开。…

题集-栈和队列的相互转化

这里&#xff0c;队列的性质是先入先出&#xff0c;但是栈的性质是后入先出。两个队列就可以通过相互捯实现数据的后入先出。 typedef int QDataType&#xff1b; //这是一个队列结点的结构 typedef struct QueueNode { struct QueueNode* next; QDataType data; }QNode; //这是…

C++之工厂模式

目录 一、为什么要使用工厂模式 优点 缺点 二、简单工厂&#xff08;Simple Factory&#xff09; 好处&#xff1a; 不足&#xff1a; 三、工厂方法&#xff1a; 好处&#xff1a; 不足&#xff1a; 四、抽象工厂&#xff08;Abstract Factory&#xff09; 一、为什…

RWA 成下一轮加密大叙事,PoseiSwap 的价值正在凸显

PoseiSwap是Nautilus Chain上的首个DEX&#xff0c;在Nautilus Chain模块化开发的支持下&#xff0c;PoseiSwap能够以更具延展性的方式来构建应用&#xff0c;并能够为交易者提供极佳的交易体验。基于Nautilus Chain支持下的Zk-Rollup方案&#xff0c;PoseiSwap构建了基于零知识…

文心一言 VS 讯飞星火 VS chatgpt (45)-- 算法导论6.1 3题

三、证明:在最大堆的任一子树中&#xff0c;该子树所包含的最大元素在该子树的根结点上。 文心一言&#xff1a; 在最大堆中&#xff0c;根结点是整个堆中最大元素的孩子&#xff0c;因此它包含的最大元素是在该子树的根结点上。 我们可以通过递归的方式证明任意子树中的最大…

C++11 线程库—互斥锁

前言 多线程因其调度的随机性和时间片分配&#xff0c;如果没有限制的访问临界资源&#xff0c;会导致出现无法预测的结果&#xff0c;也无法达到预期。 所以&#xff0c;访问临界区&#xff0c;需要是原子性的&#xff0c;在一个线程完成之前&#xff0c;不能有其他线程访问&…

找bug号召

我的博客是为了完成这个找 bug 号召&#xff1a; https://bbs.csdn.net/topics/614134877。 文章目录 测试场景之三&#xff1a; 选择你的身份 测试场景之三&#xff1a; 选择你的身份 同样在个人中心的最下面&#xff0c;你可以看到身份选择的界面。 注意&#xff0c;你要把鼠…

Python元组、集合、字典(超详细举例、讲解和区分)

总有一天你要一个人在暗夜中&#xff0c;向那座桥走过去 文章目录 一、元组 字符串、元组、列表的总结 二、集合 1.定义空集合 2.创建集合 &#xff08;1&#xff09;直接创建 &#xff08;2&#xff09;set函数 3.列表、元组、字符串、字典的去重 4.向集合中添加元素…

python---js逆向------再接再励------案例

作者前言 这是我的gitee仓库:https://gitee.com/qin-laoda/python-exercises 有兴趣的小可爱们可以点进去看看, 目录 常见的js加密算法 微信公众号的简单案例 ________________________________ 鉴于有一些小可爱对于js逆向的理解还有一些不解,下面我会再进一步的介绍js…

【计算机视觉 | 目标检测】arxiv 计算机视觉关于目标检测的学术速递(6月 23 日论文合集)

文章目录 一、检测相关(4篇)1.1 Targeted collapse regularized autoencoder for anomaly detection: black hole at the center1.2 RXFOOD: Plug-in RGB-X Fusion for Object of Interest Detection1.3 Toward Automated Detection of Microbleeds with Anatomical Scale Loca…

axios简单使用

axios简单使用 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-wid…

【杂谈】过往时期2-嵌入式求学故事线简忆

前一篇文章 过往时期 - 欢迎来到 Staok - 瞰百易 (gitee.io)。 在我兴趣广泛的过去&#xff0c;关于嵌入式方面的经历啊&#xff0c;讲一条这个的故事线。 小学&#xff0c;电子积木&#xff0c;灯泡&#xff0c;电机&#xff0c;上电发光、风扇旋转&#xff0c;风扇转的快了还…

AnyLogic仿真软件 8.8.2 Crack

AnyLogic仿真软件用于以下行业&#xff1a; 供应链 制造业 运输 仓库运营 铁路物流 矿业 石油和天然气 港口及码头 更多行业 为什么要进行仿真建模&#xff1f; 无风险环境 仿真建模提供了一种安全的方法来测试和探索不同的“假设”场景。在做出现实世界的改变之前做出正确的决…

第10章 隐式转换

第10章 隐式转换 package chapter10object Test01_TestImplicit {def main(args: Array[String]): Unit {val richInt new MyRichInt(12)println(richInt.myMax(15))// 1. 隐式函数implicit def convert(num: Int): MyRichInt new MyRichInt(num)println(12.myMax(15))// 2.…