【详解】静态库和动态库的认识和使用【Linux】

news2024/12/24 11:34:55

静态库和动态库的认识和使用

  • 静态库和动态库的概述
  • 动静态库的实现
    • 静态库
    • 动态库
    • 库文件名称和引入库的名称

静态库和动态库的概述

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

  动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。
一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文
件的整个机器码
  在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接(dynamic linking)
  动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间。

  也就是对于静态库来说,程序会在链接阶段将库函数的代码毫无保留的链接到可执行文件中,这就使得我们可以看到静态库的底层代码细节,对于静态库提供者,这带来一些不安全的问题,同时对于静态库的使用者,会显得代码臃肿。
  对于动态库来说,动态库是在程序运行时才链接的,当程序需要调用某个库文件中的函数时,操作系统会在运行时自动加载该库文件,并将其中的函数(也就是返回函数的地址)链接到程序中,动态库的底层代码细节并不对外展示,从而实现代码的共享和复用。这样,多个程序可以共享同一个库文件,从而大大减少了程序的磁盘占用空间,同时也方便了库文件的维护和更新。


那动态库的代码也是需要加载进内存的,为什么会实现简洁呢?
  :简洁是对于程序来说的,使用静态库时,静态库的整个代码都在可执行程序里面,使用动态库时,动态库只有所需函数或变量的地址被包含在程序里面。

动态库的代码是什么时候加载进内存的?
:当程序第一次调用动态库中的函数或访问动态库中的变量时,操作系统的动态链接器(或称为动态加载器)会被触发。动态链接器会根据程序中的指令,从磁盘上读取对应的动态库文件,并将其加载到进程的内存空间中。


动态库的代码是什么时候卸载的?
  :动态库的卸载不是立即发生的,而是在满足一定条件时才会进行卸载。
  当一个程序使用完动态库后,如果其他程序或进程也在使用相同的动态库,那么动态库会继续留在内存中供其他程序使用,不会被立即卸载。这是因为动态库可以被多个程序共享,避免了重复加载和占用额外内存空间。
  只有在满足以下条件时,动态库才会被卸载:

  • 引用计数为零:当所有使用该动态库的程序或进程都结束了对动态库的使用,并且没有其他程序或进程在使用该动态库时,动态库的引用计数会变为零。这表示没有程序再需要该动态库,此时动态库可以被卸载。
  • 卸载策略:操作系统或动态链接器可能还会采用一些卸载策略来决定何时卸载动态库。这些策略可能考虑到资源利用率、性能等因素,以平衡系统的需求。
      需要注意的是,动态库的卸载是由操作系统或动态链接器自动管理的,程序本身无法直接控制动态库的卸载。程序只需要在使用完动态库后正确关闭句柄或释放相关资源,让引用计数递减,卸载过程由操作系统或动态链接器负责。

动静态库的实现

  我们基于下面这些代码来封装动静态库:

/add.h/

int add(int a, int b);

/add.c/
#include "add.h"
int add(int a, int b)
{
return a + b;
}
/sub.h/

int sub(int a, int b);

/sub.c/
#include "sub.h"
int sub(int a, int b)
{
return a - b;
}

静态库

  先将代码编译为目标文件:
在这里插入图片描述


生成静态库:ar(archive)是gnu归档工具,rc表示(replace and create)

  在Unix/Linux系统中,ar命令用于创建、修改和提取静态库(archive)。ar命令的常用选项包括:

  • r: 将一个或多个目标文件添加到归档文件中,如果已经存在则替换。
  • c: 创建一个新的归档文件,如果文件已经存在,则覆盖它。
  • s: 在归档文件中添加一个符号表,用于加快链接器的符号解析速度。
  • t:显示归档文件中的成员列表。可以使用ar t libexample.a命令列出libexample.a静态库中的所有目标文件。
  • x:从归档文件中提取一个或多个成员。例如,ar x libexample.a file1.o将从libexample.a静态库中提取file1.o目标文件。
  • d:从归档文件中删除一个或多个成员。可以使用ar d libexample.a file1.o命令从libexample.a静态库中删除file1.o目标文件。
  • p:打印归档文件中的成员内容。可以使用ar p libexample.a file1.o命令将file1.o目标文件的内容打印到标准输出。
  • v: 用于在执行操作时显示详细信息。它会将操作的进度和结果打印到标准输出,以便用户可以查看每个成员的处理情况
    在这里插入图片描述
      查看静态库中的目录列表:

在这里插入图片描述
  使用静态库:

  • -L 指定库路径
  • -l 指定库名
    在这里插入图片描述
    测试目标文件生成后,静态库删掉,程序照样可以运行:

  为了实现让程序自动找到静态库:
库搜索路径

  • 从左到右搜索-L指定的目录。
  • 由环境变量指定的目录 (LIBRARY_PATH)
  • 由系统指定的目录
      /usr/lib
      /usr/local/lib
    头文件也是很重要的,所以需要将其打包成静态库和头文件组织起来。
    静态库放入lib目录下,头文件放入include下
mylib
include
lib
add.h
sub.h
libMyMath.a

头文件放入/usr/include
库文件放入/usr/lib/usr/local/lib中的任意一个
在这里插入图片描述
  使用时还需用-l指明要链接的库在哪一个路径下,因为gcc在默认路径下链接的是C/C++库,只知道内置的库,不知道第三方库,所以需要显式的说明。

动态库

生成动态库

  • shared: 表示生成共享库格式
  • fPIC:产生位置无关码(position independent code)
  • 库名规则:libxxx.so

将相关文件打包为目标文件,这里和静态库略有不同:
在这里插入图片描述
链接目标文件,将其链接成共享库文件:
在这里插入图片描述
  将生成的共享库文件安装到适当的位置,以供其他程序使用
  如果您只想让某个程序使用该共享库,而不是所有程序,可以将共享库文件放在该程序的工作目录中,或将其路径添加到LD_LIBRARY_PATH环境变量中。
在这里插入图片描述
  上面的指令可能会让大家误会,实际上将共享库文件拷贝到系统共享库路径下和更改LD_LIBRARY_PATH选择其中一种就可以了。
  如果你将共享库文件放在了系统共享库路径下,那么搜索库时会去系统共享库路径下寻找,
  如果更改LD_LIBRARY_PATH,搜索库时会去LD_LIBRARY_PATH指定的路径下去寻找,这里的是LD_LIBRARY_PATH=.这个.代表当前目录,然而上图中我们将共享库文件拷贝到系统共享库路径下了,这个更改LD_LIBRARY_PATH相当于是无意义的。

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

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


    😄 创作不易,你的点赞和关注都是对我莫大的鼓励,再次感谢您的观看😄

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

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

相关文章

【InternLM】书生-浦语大模型demo搭建服务接口部署本地映射

目录 前言一、InternLM大模型介绍1-1、大模型简介1-2、InternLM大模型简介1-2-1、InternLM-7B1-2-2、InternLM-20B 二、从0开始搭建InternLM-Chat-7B 智能对话 Demo2-0、环境搭建2-1、创建虚拟环境2-2、导入所需要的包2-3、模型下载2-4、代码克隆2-5、终端运行 三、服务器接口部…

uniapp微信小程序投票系统实战 (SpringBoot2+vue3.2+element plus ) -后端鉴权拦截器实现

锋哥原创的uniapp微信小程序投票系统实战: uniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )_哔哩哔哩_bilibiliuniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )共计21条视频…

C# 自定义配置文件序列化生成+文件格式错误自动回档

文章目录 前言选择Xml简单的Xml使用测试用例简单的写简单的读简单的生成配置修改配置类测试用例运行结果对比 代码逻辑封装逻辑示意封装好的代码测试生成配置文件格式错误测试使用默认值覆盖来解决问题 配置文件人为修改错误如何解决解决方案代码测试用例运行结果 代码封装总结…

Linux系统使用超详细(八)~磁盘管理

目录 一、认识磁盘 二、磁盘运行机制 三、磁盘检查 3.1查找设备名称和分区号 3.1.1使用lsblk命令: 3.1.2使用fdisk命令: 3.1.3使用blkid命令: 3.2检查方向 3.2.1文件系统完整性: 3.2.2磁盘健康状态: 3.2.3磁…

C#,深度优先搜索(DFS)、广度优先搜索(BFS)算法的源代码与数据可视化

概述 下载源代码: 链接:https://pan.baidu.com/s/1sLxMT78LVg2dWyXXFvM--w?pwd2kwl 提取码:2kwl --来自百度网盘超级会员V5的分享https://pan.baidu.com/s/1sLxMT78LVg2dWyXXFvM--w?pwd2kwl 深度优先搜索(亦称深度优先遍历&a…

uniapp选择android非图片文件的方案踩坑记录

这个简单的问题我遇到下面6大坑,原始需求是选择app如android的excel然后读取到页面并上传表格数据json 先看看效果 uniapp 选择app excel文件读取 1.uniapp自带不支持 uniapp选择图片和视频非常方便自带已经支持可以直接上传和读取 但是选择word excel的时候就出现…

红外传感器(含代码注释)

一.引言 红外传感器是一种能够检测和测量红外光的传感器。由于红外光的特性,红外传感器在许多领域中得到了广泛的应用,如军事、航空航天、医疗、环保、工业控制等。本文将详细介绍红外传感器的原理、应用以及未来发展趋势。 二.红外传感器的工作原理 红外…

Vue3-41-组件- 动态组件 component 标签 和 is 属性 的使用

说明 <component> 标签 有一个 is 属性&#xff0c; 可以给这个 is属性 赋值为一个 组件对象&#xff0c; 这样这个<component> 标签就可以渲染指定的组件对象了。 使用案例 本案例中会 准备两个简单的组件&#xff0c; 在 App.vue 中导入这两个组件&#xff0c;并…

Thonny开发ESP32点灯

简介 ESP32是一款功能强大的低功耗微控制器&#xff0c;由乐鑫&#xff08;Espressif&#xff09;公司开发。它集成了Wi-Fi和蓝牙功能&#xff0c;适用于各种物联网应用。Thonny是一款基于Python的开源集成开发环境&#xff08;IDE&#xff09;&#xff0c;专为MicroPython设计…

SpringBoot学习(六)-SpringBoot整合Shiro

12、Shiro 12.1概述 12.1.1简介 Apache Shiro是一个强大且易用的Java安全框架 可以完成身份验证、授权、密码和会话管理 Shiro 不仅可以用在 JavaSE 环境中&#xff0c;也可以用在 JavaEE 环境中 官网&#xff1a; http://shiro.apache.org/ 12.1.2 功能 Authentication…

【Leetcode】230. 二叉搜索树中第K小的元素

一、题目 1、题目描述 给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数)。 示例1: 输入:root = [3,1,4,null,2], k = 1 输出:1示例2: 输入:root = [5,3,6,2,4,null,null,1], k = 3 输出:3提示: 树中…

Supershell反溯源配置

简介 项目地址&#xff1a;https://github.com/tdragon6/Supershell Supershell是一个集成了reverse_ssh服务的WEB管理平台&#xff0c;使用docker一键部署&#xff08;快速构建&#xff09;&#xff0c;支持团队协作进行C2远程控制&#xff0c;通过在目标主机上建立反向SSH隧…

1389 蓝桥杯 二分查找数组元素 简单

1389 蓝桥杯 二分查找数组元素 简单 //C风格解法1&#xff0c;lower_bound(),通过率100% //利用二分查找的方法在有序的数组中查找&#xff0c;左闭右开 #include <bits/stdc.h> using namespace std;int main(){int data[200];for(int i 0 ; i < 200 ; i) data[i] …

Android 15即将到来,或将推出5大新功能特性

Android15 OneUI电池优化 三星最近完成了对其所有设备的稳定版 One UI 6.0 更新的推出&#xff0c;引起了用户的极大兴奋。据新出现的互联网统计数据显示&#xff0c;即将发布的基于 Android 15 的 One UI 7 将通过优化电池和功耗来重新定义用户体验&#xff0c;这是一项具有突…

听GPT 讲Rust源代码--compiler(19)

File: rust/compiler/rustc_target/src/spec/mips_unknown_linux_gnu.rs 该文件&#xff08;rust/compiler/rustc_target/src/spec/mips_unknown_linux_gnu.rs&#xff09;是Rust编译器针对MIPS架构上的Linux系统的目标描述文件。它的作用是定义了在这个目标上编译时的一些配置…

商品砍价系统设计原理与实践:技术解析与注意事项

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

Java序列化篇----第一篇

系列文章目录 文章目录 系列文章目录前言一、什么是java序列化,如何实现java序列化?二、保存(持久化)对象及其状态到内存或者磁盘三、序列化对象以字节数组保持-静态成员不保存四、序列化用户远程对象传输前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,…

第16课 播放rtsp流

在现实生活中有许多rtsp摄像头&#xff0c;这些摄像头如果能充分利用起来可以生成很多有趣、有用的应用&#xff1a;比如户外互动大屏等。在第4课&#xff0c;我们实现了一个播放器&#xff0c;当时来用它播放rtmp流和mp4时它好象工作的很好。这节课我们就用它来播放rtsp流试试…

物联网产品中,终端、网关、协议、PaaS、SaaS之间的关系

在互联网产品中&#xff0c;经常提到的终端、网关、协议、PaaS、SaaS之间&#xff0c;到底有什么关系呢&#xff1f; 一、基本概念 在百度/其他地方搜集的信息中&#xff0c;对于终端、网关、协议、PaaS、SaaS的解释各有不同&#xff0c;整理如下&#xff1a; 终端&#xff1…

CMU15-445-Spring-2023-Project #1 - Buffer Pool

前置知识&#xff0c;参考上一篇博客&#xff1a;CMU15-445-Spring-2023-Project #1 - 前置知识&#xff08;lec01-06&#xff09; 在存储管理器中实现缓冲池。缓冲池负责将物理页从主内存来回移动到磁盘。它允许 DBMS 支持大于系统可用内存量的数据库。缓冲池的操作对系统中的…