Linux —— 动静态库

一、基本认识

1.什么是库?

在编译C或C++时,在使用一些函数时,我们都需要先声明头文件,头文件中一般存放着这些函数的声明,而具体的实现方法,一般就被放在库中,库文件在编译链接的阶段会被链接到可执行程序中,本质是实现方法的二进制文件打包成的库文件

2.动态库和静态库的区别

我们使用的各种c库封装好的函数时,在编译生成可执行程序时一定要有对应的实现方法,这些实现方法在编译到链接的阶段,编译器需要通过头文件中的声明去找到具体的实现方法,也就是需要库,动态库和静态库的区别就是,静态库在此时会将具体的实现方法代码直接拷贝链接到可执行程序中,一旦生成可执行程序,可执行程序的执行不依赖静态库,而动态库在链接阶段只是将该动态库的地址等各种信息记录到可执行程序中,只有当程序执行时,才会真正的去将具体实现的方法加载到内存中,并且通过地址等各种信息去找到具体实现方法,因此,动态链接生成的可执行程序是依赖库的。

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

3.为什么要有库?

库实际就是各种函数的具体实现方法,在实际开发中,会存在大量的重复功能的需求,为了节省开发的成本,提高效率,我们可以将常用的各种功能打包成库,提供给别人使用,也可以下载别人已经实现好的库,提高开发效率

二、动静态库的制作

1.前提知识

1.1 库的命名

动态库和静态库都会以lib为前缀

动态库的后缀为:.so

静态库的后缀为:.a

库的实际名字是去掉前缀和去掉后缀的

1.2 云服务器中默认只有动态库

一般的云服务器都只会存在动态库,静态库需要自己安装下载

1.3 库文件的本质

接下来会用一个例子去体现如何打包制作库,以及如何使用库,实际就是将我们具体的实现方法的文件进行编译到二进制文件阶段,然后将所有的二进制文件进行打包成一个库文件,这个过程就是制作库的过程

1.4 前提准备

接下来,我们简单的用一个例子去演示库文件的打包和使用,我们自己实现一个加法和减法的功能,并且将这两个功能分别用放在不同的文件,声明放在不同头文件中(为了演示多个文件如何打包成库),因此先简单做以上的准备

2.静态库的打包

2.1 先将实现方法文件编译到二进制文件

2.2 将二进制文件打包制作静态库

3.动态库的打包

3.1 形成二进制文件

同样用gcc编译形成二进制文件,但与静态库有所不同,需要添加一个命令行参数 -fPIC(与位置无关码),至于为什么,在后面关于动态库的理解中会有解释

3.2 制作动态库

与静态库不同,直接使用gcc指令即可制作动态库,需要添加命令行参数-shared

三、动静态库的使用

1.前提知识

1.1 gcc在编译时对头文件和库文件的搜索策略

2. 静态库的使用

在使用gcc编译时,若是需要使用第三方库,根据gcc的搜索策略,我们需要指定头文件和库文件所在路径,或者将文件所在路径配置到环境变量或者系统默认目录中

示例:

首先,假设我们将第三方库和头文件下载到了当前工程main文件的目录下,分别放在了include和lib目录下

需要指定路径去编译

实际在下载第三方库时,系统通常会默认下载到系统默认路径下,在Linux下,对任意软件而言,安装和卸载的本质就是拷贝到系统特定的路径下

注意,即便是已经将库和头文件都配置到系统默认路径下了,在使用gcc或g++编译时,依然要指定库的具体名称

3.动态库的使用

3.1 前提知识

和使用静态库时一样,我们也需要告诉gcc编译器头文件和库文件的路径,但是,不同的是,因为静态库的链接方式是直接将库内的代码直接拷贝到编译生成的可执行程序中,而动态链接则是需要在可执行程序被运行时,通过进程由OS去找到库的内容,因此还需要让OS找到库的位置

3.2 系统路径

OS会到系统默认路径去找,我们要如何知道或者配置当前的系统路径?系统默认查找路径可以在环境变量中配置和查看

查看系统路径:

3.3 使用动态库示例

示例一:采用修改环境变量的方式,让系统能够找到和链接到动态库(临时方案)

示例二:在系统默认搜索路径下建立软链接指向库所在路径

示例三:配置系统文件

四、动态库的理解

在系统层面加载链接一个动态库具体是如何的呢?

首先一个程序在被编译时,采用动态链接编译通过后,生成的可执行程序中,里面包含着关于这个动态库的各种信息

该可执行程序被执行时,OS会创建一个进程,有对应的task_struct、虚拟地址空间、页表,该可执行程序的代码被加载到物理内存后,通过页表映射到虚拟地址的代码区,而当代码执行到需要动态链接库的实现方法的部分时,OS才会根据可执行程序中关于动态库的地址路径找到动态库,将该动态库加载到物理内存中,再建立页表映射关系,动态库的内容会被放到虚拟地址的共享区部分(堆栈中间的那部分空间),然后系统根据需要的方法实现的偏移量信息,找到具体的实现方法

当有其他进程也要用到该库中的方法时,只需要页表建立映射关系,并且记录各个实现方法的偏移量,在虚拟空间分配好虚拟地址后,通过偏移量去找到具体实现方法即可,这也是fPIC(与位置无关码)的作用

五、细节补充

1.在动态库和静态库同时存在时,OS会默认采用动态链接,若是要指定静态链接,需要加上命令行参数-static

2.云服务器一般只提供动态库,若是需要C和C++的静态库,可以使用yum进行安装

yum install -y glibc-static 

yum install -y libstdc++-static

3. 与位置无关码的作用是在生成动态库时,动态库中的不同方法实现的位置信息都采用偏移量的方式去记录

总结

本篇整理总结了关于动静态库的制作和使用,已经动态链接在系统层面上该如何看待,之后在一些项目开发时,会经常使用到第三方库,因此其中的指令和如何使用非常重要

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PADS做CAM文件时,提示填充宽度对于精确的焊盘填充过大

1、开发环境: PADS VX1.2 2、问题复现: 同一个PCB文件,设计验证没有错误。但是输出CAM光辉文件时,总是弹出“填充宽度对于精确的焊盘填充过大,填充宽度……”,如下图: 3、错误的方法&#xff1…

未来已来:Facebook的数字革命与社交转型

在当今数字化时代,Facebook作为全球最大的社交网络之一,不仅扮演着连接人们的桥梁,更是引领着社交行业的数字革命与转型。本文将深入探讨Facebook如何通过创新技术、改变用户体验以及应对挑战,塑造了未来社交的面貌,以…

Python数据处理,使用 tkinter 模块点击获取文件目录

Python数据处理,使用 tkinter 模块点击获取文件目录 正文 正文 当我们进行数据处理读取文件内数据的时候,通常,我们需要设定好一个存放当前文件所在目录的变量。比如如下目录: file_path rC:\Users\xxx\Desktop\DataSet\Data.c…

使用DataGrip连接跳板机后再连接远程服务器的mysql数据库

相比配置本地数据库就是多了一步SSH/SSL配置。 添加新的mysql连接,选择SSH/SSL,勾选Use SSH tunnel: 点击右边的…配置跳板机连接,输入账号密码,然后保存: 接着配置General,里面填上要连接的数…

了解运维基础

一、运维概述 1、运维岗位的收入情况 2、运维的职位定义 什么是运维? 在技术人员之间,一致对运维有一个开玩笑的认知:运维就是修电脑的、装网线的、背锅的岗位。 其实不然,运维是一个非常广泛的定义,在不同的公司不同…

洗地机有哪些牌子比较好?洗地机排行榜十大品牌

随着洗地机市场竞争的日益激烈,市场上涌现出数百个品牌的产品,涵盖了从入门级到高端的各类价位和功能。这种多样化的选择一方面极大地满足了用户的不同需求,但另一方面也让消费者在挑选时面临一定的困扰。在众多种类的洗地机中,如…

Redis之内存管理过期、淘汰机制

1.Redis内存管理 我们的redis是一个内存型数据库,我们的数据也都是放在内存中的,内存是有限的空间,当数据满了之后,我们要怎么样继续保证redis的可用性呢?我们就需要采取点管理措施和机制来保证我们redis的可用性。 在redis.co…

人脸检测--FaceNet(四)

FaceNet 是一个由 Google 研究团队开发的人脸识别系统,它基于深度学习技术,可以实现高精度的人脸识别、验证和聚类任务。FaceNet 通过学习直接从图像像素到人脸嵌入的映射,使得它在各种人脸识别任务中表现出色。下面是对 FaceNet 的详细介绍&…

Mac 安装 Adobe 软件报错 “The installation cannot continue as the installer file may be damaged. “

文章目录 1. 引言2. 解决方法2.1 打开“任何来源”2.2 安装应用2.3 关闭“任何来源” 3. 学习用途,下载 Adobe 软件4. 参考 1. 引言 Mac 用户再安装 Adobe 的产品,如 After Effects 时,报错: "The installation cannot continue as th…

如何恢复被盗的加密货币?

本世纪,网络犯罪的首要目标是加密货币。 这要归功于加密货币的日益普及和价值,网络犯罪分子已经认识到经济收益的潜力,并将重点转向利用这种数字资产中的漏洞。 在今天的文章中,我们将讨论加密货币恢复和被盗加密货币恢复。 我们…

【图论】最短路(一)

发现之前做的题很乱,用小笔记把看过的博客和题目分类记录一下, 代码参考了很多佬,是标注出来的链接,若不同意我就删掉(鞠躬) 找了几张好点的,图来源图中的id和acwing 1.dijkstra 依次找到距…

Android设备获取OAID调研和实现

什么是OAID、AAID、VAID OAID OAID是"Android ID"(安卓ID)的一种替代方案,其全称为"Open Anonymous Identifier"(开放匿名标识符)。 因传统的移动终端设备标识如国际移动设备识别码(…

免费,Python蓝桥杯等级考试真题--第17级(含答案解析和代码)

Python蓝桥杯等级考试真题–第17级 一、 选择题 答案:B 解析:(x-y)%25%21,故答案为B。 答案:B 解析:x16,所以i的值为range(1,16),取值为1-15&…

Dinky MySQLCDC 整库同步到 MySQL jar包冲突问题解决

资源:flink 1.17.0、dinky 1.0.2 问题:对于kafka相关的包内类找不到的情况 解决:使用 flink-sql-connector- 胖包即可,去掉 flink-connector- 相关瘦包,解决胖瘦包冲突 source使用 flink-sql-connector- 胖包&#…

【数据库】通过一个实例来认识数据流图DFD

导读:通过一个实例(数据中台)说明数据流图DFD的作用、介绍了常见的数据流图元素及其标准符号以及如何画数据流图。数据流图主要被分析师、系统设计师、流程优化专家、系统管理员以及与系统开发和维护相关的人员查看和使用。对于刚考完2024年5…

Altium Designer软件下载安装「专业PCB设计软件」Altium Designer安装包获取!

Altium Designer,这款软件凭借其全面的设计流程覆盖,从概念到实现,都能为电子工程师提供强大的支持。 在硬件设计方面,Altium Designer提供了丰富的元件库和灵活的布局选项,使得工程师能够轻松地进行电路设计&#xff…

反射机制大揭秘-进阶Java技巧,直击核心!

反射在Java中扮演着重要的角色,掌握了反射,就等于掌握了框架设计的钥匙。本文将为您逐步讲解反射的基本概念、获取Class对象的三种方式、使用反射实例化对象并操作属性和方法,还有解析包的相关内容。跟随我一起探索反射的奥秘,提升…

学习Java的日子 Day48 函数,DOM

Day48 1.流程控制语句 if else for for-in(遍历数组时,跟Java是否一样) While do while break 语句用于跳出循环 continue 用于跳过循环中的一个迭代 2.函数 2.1 JavaScript 函数语法 函数就是包裹在花括号中的代码块,前面使用了关键词 function funct…

数据分析必备:一步步教你如何用Pandas做数据分析(11)

1、Pandas 自定义选项 Pandas 自定义选项操作实例 Pandas因为提供了API来自定义行为,所以被广泛使用。 自定义API中有五个相关功如下: get_option() set_option() reset_option() describe_option() option_context() 下面我们一起了解下这些方法。 1.…

【移动云】主机ECS搭建项目——具体步骤教程

目录 一、什么是移动云 二、移动云有什么优势 三、移动云使用 1.注册账号 2.云主机ECS创建 3.管理云主机 4.连接配置云主机 5.搭建服务器提示与建议 四、使用感受 一、什么是移动云 移动云是中国领先的云服务品牌之一,它以强大的资源优势、技术实力和品牌价…