【Linux】动静态库的使用与软链接的结合

news/2023/12/1 0:24:15

文章目录

  • 前言
  • 一、静态库
    • 1.静态库的创建
    • 2.静态库的链接
    • 3.将库进行打包
    • 4.链接方法:
      • 1.直接链接
      • 2.拷贝到系统路径里面
      • 3.采用软链接方法
  • 二、动态库
    • 1.解决加载找不到动态库的方法
      • 1.直接拷贝
      • 2.建立软链接
      • 3.建立自己的动态路径配置文件
    • 2.为什么动态库权限需可执行而静态库没有
  • 三、关于地址
    • 1.程序没有加载前的地址(程序)
    • 2.程序加载后的地址(进程)
    • 3.动态库使用


前言

库本质就是把一堆(.o)后缀的文件也就是目标文件整合在一起
在这里插入图片描述

一、静态库

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

1.静态库的创建

[root@localhost linux]# gcc -c mymath.c -o mymath.o
先把文件变成目标文件
生成静态库
[root@localhost linux]# ar -rc libmymath.a   mymath.o 
ar是gnu归档工具,rc表示(replace and create)格式:
ar -rc 静态库名字(注意格式)  静态库所包含的目标文件

2.静态库的链接

在这里插入图片描述

3.将库进行打包

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

1.第三方库的使用,gcc往后必须加上 -l +库名
2.如果系统中只提供静态链接,则gcc对其进行静态链接
3.如果系统中链接多个库,则直接在gcc后面加上指定路径和库的名字就可以

4.链接方法:

1.直接链接

在这里插入图片描述

2.拷贝到系统路径里面

在这里插入图片描述

一般系统里头文件都在/usr/include
库都在/lib64

将我们的库放到系统路径下,我们就不需要在编译的时候指定我们的路径了,因为系统会自己到系统路径中找,但我们还是要带上我们的库名的,这是规定

3.采用软链接方法

先为头文件部分以及库文件创建软链接放入系统路径中去
在这里插入图片描述
在这里插入图片描述
编译链接
在这里插入图片描述

二、动态库

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

//生成目标文件,需要带-fPIC
[root@localhost linux]# gcc -fPIC -c myprint.c mylog.c 
//创建动态库
[root@localhost linux]# gcc -shared -o libmymath.so  *.o  

在这里插入图片描述

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

我们前面只告诉了编译器我的动态库在什么位置,但当我程序运行起来的时候就和编译器没关系了,所以我们也要告诉系统(加载器)我的动态库放在哪里!!!
静态链接能找到是因为我们静态库直接整个干到可执行文件里面了,根本不需要去找静态库,因为已经和我原来的可执行程序融为一体了

1.解决加载找不到动态库的方法

1.直接拷贝

和静态库类似,直接拷贝到系统默认库路径 /lib64

2.建立软链接

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

3.建立自己的动态路径配置文件

ldconfig 配置/etc/ld.so.conf.d/,ldconfig更新

不认动态库名,只需放入动态库路径,因为当时我们告诉过编译器我们用哪个库了
在这里插入图片描述
将动态库路径写入创建的conf文件
在这里插入图片描述
在这里插入图片描述
重新ldconfig后,我们就能找到动态库的路径,而且是全局有效
在这里插入图片描述

2.为什么动态库权限需可执行而静态库没有

因为我们静态库直接拷贝到源文件中,拷贝完成后,后续程序运行的时候就用不到了,因为我内部已经有了,而我动态库要以可执行程序的形式加载到内存中与可执行程序产生关联,静态库不需要加载到内存

三、关于地址

动态库在内存中加载会被所有程序共享,动态库在运行的时候是要被加载到内存中的

1.exe加入到物理内存后与页表建立映射关系,当需要使用动态库的时候,动态库也会用类似的方法加入到内存中,之后2.exe也要使用和1.exe相同的动态库,操作系统知道库的加载情况,检测到那个库已经加载到内存里面不需要再加载一遍了,所以直接改变进程2的页表,让动态库与其共享区建立联系

在这里插入图片描述

1.程序没有加载前的地址(程序)

编译器也要为操作系统考虑,程序编译后之后,内部就已经有地址了,这里的地址现在来看其实就是虚拟地址

在这里插入图片描述

2.程序加载后的地址(进程)

问:如何执行我们的第一条命令呢?

答:
其实我们在编译好文件的时候,文件中会有一个entry即入口地址存在于表头,我们CPU中的PC会载入程序的入口地址,这个入口地址是虚拟地址,所以我们要借助页表去寻找其物理地址,但因为此时我们入口地址对应的物理地址还未写入页表,这个时候就会发生缺页中断,该程序会加载到物理内存中,物理地址与虚拟地址的映射关系也会被写入页表中,这样就完成了一个循环过程,我执行下面的指令如果没有对应的物理地址会发生缺页中断写入页表

重点:
⭕与此同时,操作系统会为程序对应的进程构建进程地址空间,并让进程中的指针指向其对应的进程地址空间。
当CPU要运行这段进程时,操作系统会把地址空间代码区的code_start送入CPU,CPU进入代码区后从main函数作为入口开始执行程序
🚩而因为编译器在编译程序代码内部的逻辑地址时,同样也是遵循进程地址空间的规则来编址的,所以当为进程构建地址空间时,其地址空间中的各个虚拟地址是直接使用编译器在编译可执行程序时生成的逻辑地址。
所以当CPU要开始执行程序时,是拿到了main函数的虚拟地址,再通过页表映射到物理内存中的物理地址,找到main函数加载到内存中的代码数据并运行,而在main函数运行的过程中进行了fun函数的调用,这时CPU读取到的依旧是fun函数的虚拟地址(可执行程序中的逻辑地址),然后再次通过页表映射到物理内存中的物理地址

CPU在运行时,读取的都是指令,指令中便包含了地址,而自始至终,CPU读取的都是虚拟地址,没有见过物理地址

在这里插入图片描述

3.动态库使用

问:我们可执行程序,如何找到动态库中我们要使用的特定部分呢?
*
答:页表中会存储动态库的起始位置的虚拟地址与物理地址的链接,动态库直接采用偏移量对库中函数进行编址,我们知道printf的偏移量后再知道动态库的起始地址,就能再动态库中找到printf

在这里插入图片描述


http://www.ppmy.cn/news/1231371.html

相关文章

Notpad-- ubuntu下载安装

Notpad-- ubuntu下载安装 下载 Gitee链接: https://gitee.com/cxasm/notepad– 安装 sudo apt install *.deb运行 /opt/apps/com.hmja.notepad/files/Notepad--出错 需要安装qt5 sudo apt-get install qt5-default

关于sqlModel 实现查询表单入参空值和模糊匹配一次性查询

在处理表单提交后,后端 SQL 查询部分空值和部分模糊值时,可以使用 SQLModel 构建动态查询。你可以根据表单数据动态构建 SQL 查询,并且只添加那些非空的、有值的条件。 以下是一个示例,假设你有一个模型 Item: from …

如何修改百科内容?百度百科内容怎么修改?

百科词条创建上去是相当不易的,同时修改也是如此,一般情况下,百科词条是不需要修改的,但是很多时候企业或是人物在近期收获了更多成就或是有更多的变动,这个时候就需要补充维护词条了,如何修改百科内容&…

金蝶云星空套打设计

文章目录 金蝶云星空套打设计下载登录打开需要创建套打的单据新建套打模板数据中心-发货通知单-设置预览 金蝶云星空套打设计 下载 登录 打开需要创建套打的单据 KD开头,是标准产品预设。 新建套打模板 默认A4纸 默认插入三行三列。 拖入文本,填写内容…

VR全景打造亮眼吸睛创意内容:三维模型、实景建模

随着VR技术在不同行业之间应用落地,市场规模也在快速扩大,VR全景这种全新的视觉体验为我们生活中的许多方面都带来了无限的可能。更加完整的呈现出一个场景或是物体的所有细节,让浏览者感受到自己仿佛置身于现场一般;其次&#xf…

开启金融之门,一切皆有可能——人大女王金融硕士项目助您成就辉煌

在这个充满无限可能的世界里,每个人都有自己的梦想和追求。对于许多人来说,拥有一份高薪、有前景的工作是他们的梦想。而要实现这个梦想,除了自身实力外,好的学历和丰富的资源也至关重要。今天,我们就来为大家介绍一个…

捷诚管理信息系统 SQL注入漏洞复现

0x01 产品简介 捷诚管理信息系统是一款功能全面,可以支持自营、联营到外柜租赁的管理,其自身带工作流管理工具,能够帮助企业有效的开展内部审批工作。 0x02 漏洞概述 捷诚管理信息系统CWSFinanceCommon.asmx接口存在SQL注入漏洞。未经身份认…

crontab配置定时根据名称杀进程

服务器上某个进程杀掉后会重启,怀疑是被当成肉鸡,因此是用linux自带的crontab定时执行脚本杀掉进程 上传脚本文件到服务器 #! /bin/bash # 要杀掉进程的名称 APPLICATION"ntools"if pkill -f "${APPLICATION}"; thenecho "${…

【路径最全用法】python代码讲解os.path包的最全用法

目录 概览 🚗🚗os.getcwd() 🚗🚗os.chdir() 🚗🚗os.path.abspath(path) 🚗🚗os.path.basename(path) 🚗​​​​​​​🚗os.path.dirname(path) &#…

Vscode GDB 查看内存的值

在VSCode的GDB图形界面中,你可以使用"调试控制台(Debug Console)"来查看malloc返回的地址里的值。以下是具体的步骤: 首先,你需要在你的代码中设置一个断点,这个断点应该在malloc函数调用之后,这样你可以获…

目标检测标注工具AutoDistill

引言 在快速发展的机器学习领域,有一个方面一直保持不变:繁琐和耗时的数据标注任务。无论是用于图像分类、目标检测还是语义分割,长期以来人工标记的数据集一直是监督学习的基础。 然而,由于一个创新性的工具 AutoDistill&#x…

JVM:内存模型、内存分配机制、内存分配冲突、JVM垃圾标记算法、JVM1.8增加元数据区缘由

文章目录 JVM 内存模型线程共享区:堆方法区(元空间) 线程私有区线程栈 本地方法栈程序计数器 为什么JDK1.8会增加对方法区的实现/为什么JDK1.8将方法区更改为元数据区JVM内存分配机制指针碰撞空闲列表 内存分配冲突CAS乐观锁解决TLAB解决 JVM垃圾标记算法1、引用计数…

JOSEF约瑟 数显电压继电器 HYJY-30-02 AC220V 导轨安装

HYJY系列电压继电器 HYJY-30-01集成电路电压继电器 HYJY-30-01A HYJY-30-01B HYJY-30-02集成电路电压继电器 HYJY-30-02A HYJY-30-02B HYJY-30-03-3集成电路电压继电器 HYJY-30-03-2 HYJY-30-03-1 HYJY-30-02电压继电器(以下简称继电器)用于发…

数字化转型导师坚鹏:数字化时代银行网点厅堂营销5大重点分析

数字化时代银行网点厅堂营销存在以下5大重点: 1、厅堂宣传。应以主推产品作为厅堂宣传的宣传重点,结合视频宣传、平面物料、互动机具、陈列物料等多维度,开展有序重复展示,进而加大吸引客户关注度。 2、产品推荐。在识别出中高端…

自动化物流运输设备模组要选择哪种类型?

在自动化物流运输设备中,选择合适的模组类型取决于具体的运输需求和应用场景。 1、同步带模组:同步带模组是一种低噪音、低成本的物流运输设备,适用于中短距离、轻型货物的运输。它采用同步带传动的方式,具有传动准确、运行稳定、…

一个快递包裹的跨国之旅

事情要从今年三月份说起,一位爱尔兰的同事在6月份结婚,团队同事准备了中国风的丝绸画轴、领带、丝巾作为礼物。3月份开始邮寄,4月初爱尔兰方面收件,5月份因为文件不足、不完整、不正确等原因被取消进口,7月份退回到大连…

Linux应用开发基础知识——网络通信编程(九)

前言: 通过学习为后续Linux网络编程奠定基础。首先介绍网络编程的概念,即网络协议分层,旨在帮助读者对网络建立初步的、全面立体的认识,其次介绍包括协议、端口、地址等;最后介绍应用非常广泛的传输控制协议&#xff0…

Nessus扫描结果出现在TE.IO或者ES容器结果查看问题解决方案

Nessus扫描结果出现在TE.IO或者ES容器结果查看问题解决方案 也是昨天晚上折腾了一个晚上到凌晨四点多,实在没有头绪,在论坛,贴吧,各种求助查贴,没有什么人解决.后面请教了一个安全圈的大佬朋友给解决了. 我的问题是在kali上的,所以只写了kali 的解决方案: 修改插件: vim /opt/…

DeepStream--测试lpdnet车牌检测模型

模型地址:https://catalog.ngc.nvidia.com/orgs/nvidia/teams/tao/models/lpdnet/version 模型格式已经从加密的etlt格式变为onnx格式。这个模型用于从汽车图片上检测出车牌位置,模型有两个,一个用于美国车,一个用于中国车。 Nv…

安卓老项目改造为AndroidX

由于涉及到了包名的改动,如果从Android Support Library升级到AndroidX需要手动去改每一个文件的包名,那可真得要改死了。(*是的我改完才发现这个办法,给我改到深呼吸,气人! *) 为此&#xff0c…
最新文章