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

news2024/11/16 11:33:19

文章目录

  • 前言
  • 一、静态库
    • 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.coloradmin.cn/o/1227143.html

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

相关文章

C#入门(1):程序结构、数据类型

一、C#程序结构 第一个C#程序 using System;namespace base_01 {class Program{#region 代码折叠块static void Main(string[] args){//控制台输出Console.WriteLine("Hello World!");Console.Write("C#是微软的编程语言"); //不换行输出//Console.Rea…

相机内参及其内参影响因素的几点思考

目录 理论推导之从相机坐标系到像素坐标系 机械参数对相机内参的影响 Resize与Crop对相机内参的影响 参考文献 理论推导之从相机坐标系到像素坐标系 相机内参的意义即从相机坐标系到像素坐标系的表达,其中共涉及到三个坐标系:相机坐标系、成像坐标系…

2023年【安全员-A证】报名考试及安全员-A证新版试题

题库来源:安全生产模拟考试一点通公众号小程序 安全员-A证报名考试是安全生产模拟考试一点通总题库中生成的一套安全员-A证新版试题,安全生产模拟考试一点通上安全员-A证作业手机同步练习。2023年【安全员-A证】报名考试及安全员-A证新版试题 1、【多选…

AIGC ChatGPT4 读取接口文件并进行可视化分析

数据分析的过程中,对数据文件进行可视化分析是每个数据分析师必备的技能。如下图数据源。 现在需要对各地区的销量进行汇总,使用Python来进行分析。 但是又不想写代码,或者不会Python代码,可以用ChatGPT4来帮我们完成代码的编写。 完整的Python代码: import pandas as p…

【深度学习实验】注意力机制(一):注意力权重矩阵可视化(矩阵热图heatmap)

文章目录 一、实验介绍二、实验环境1. 配置虚拟环境2. 库版本介绍 三、实验内容0. 理论介绍a. 认知神经学中的注意力b. 注意力机制: 1. 注意力权重矩阵可视化(矩阵热图)a. 导入必要的库b. 可视化矩阵热图(show_heatmaps&#xff0…

Linux:补充一些常用命令

Linux:补充一些常用命令 1. free -h2. df -lh3. du -sh *4. uname -a5. which6. mvn install 编译打包7. find -name *.jar8. cd -9. nohup java -jar *.jar &10. ps -ef|grep java11. netstat -ntlp 1. free -h free 命令显示系统使用和空闲的内存情况&#x…

3DMAX森林树木植物插件ForestPackLite教程

3DMAX森林树木植物插件ForestPackLite教程 Forest Pack是世界上最受欢迎的散布插件。它提供了一个完整的解决方案来创建大面积的物体,从树木和植物到建筑、人群、骨料、地面覆盖物、岩石等等。如果你能为它建模,森林包就能把它分散开来。 无数工作室依靠…

windows排除故障工具pathping、MTR、sysinternals

pathping 基本上可以认为它是ping和tracert的功能合体。 pathping首先对目标执行tracert,然后使用ICMP对每一跳进行100次ping操作。 如图,是一个对8.8.8.8进行pathing操作。 MTR MTR是另一个多工具合体工具。 winmtr是mtr的windows版本。 这个工具…

数据分析思维与模型:群组分析法

群组分析法,也称为群体分析法或集群分析法,是一种研究方法,用于分析和理解群体内的动态、行为模式、意见、决策过程等。这种方法在社会科学、心理学、市场研究、组织行为学等领域有广泛应用。它可以帮助研究人员或组织更好地理解特定群体的特…

Java多线程核心技术第一阶段-Java多线程基础 02

接上篇:Java多线程核心技术第一阶段-Java多线程基础 01 3.3 清除中断状态的使用场景 this.interrupted()方法具有清除状态标志值的功能,借用此特性可以实现一些效果。 【示例3.3.1】在MyThread4线程中向list1和list2存放数据,基于单一职责原…

Docker中的RabbitMQ已经启动运行,但是管理界面打不开

文章目录 前言一、解决方法方法一方法二 总结 前言 肯定有好多小伙伴在学习RabbitMQ的过程中,发现镜像运行,但是我的管理界面怎么进不去,或者说我第一天可以进去,怎么第二天进不去了,为什么每次重新打开虚拟机都进不去…

Linux 基本语句_11_无名管道文件复制

父子进程&#xff1a; 父子进程的变量之间存在着读时共享&#xff0c;写时复制原则 无名管道&#xff1a; 无名管道仅能用于有亲缘关系的进程之间通信如父子进程 代码&#xff1a; #include <stdio.h> #include <unistd.h> #include <sys/types.h> #inc…

IDEA 搭建 SpringCloud 项目【超详细步骤】

文章目录 一、前言二、项目搭建1. 数据库准备2. 创建父工程3. 创建注册中心4. 服务注册5. 编写业务代码6. 服务拉取 一、前言 所谓微服务&#xff0c;就是要把整个业务模块拆分成多个各司其职的小模块&#xff0c;做到单一职责原则&#xff0c;不会重复开发相同的业务代码&…

HC-SR501传感器制作一个报警系统

接线图&#xff1a; 引脚连接&#xff1a; 1. 将 PIR 信号引脚连接到 arduino 数字 引脚 13。 2. 将 PIR V 引脚连接 到 arduino 5v 引脚。 3. 将 PIR GND 引脚连接到 arduino GND 引脚。 4. 将arduino数字 引脚12连接 到220欧姆电阻&#xff0c;并将该电阻连接到 LED V …

用户增长模型:3A3R策略模型

一、概述 A - A - A - R - R - R 增长模型&#xff0c;即3A3R策略模型&#xff0c;由海盗模型演变而来&#xff0c;是目前使用最多、适用范围最广的增长策略模型。原始的海盗模型由 Acquisition &#xff08;获客&#xff09;、 Activation &#xff08;活跃&#xff09;、 Re…

mfc140.dll是什么文件?如何修复mfc140.dll丢失的方法分享

​mfc140.dll丢失的原因 未正确安装Microsoft Visual C Redistributable&#xff1a;mfc140.dll是Visual C库的一部分&#xff0c;如果没有正确安装Visual C Redistributable&#xff0c;可能导致mfc140.dll丢失。 系统文件损坏&#xff1a;由于病毒感染、系统错误或其他原因…

Java面向对象(高级)-- 单例(Singleton)设计模式

文章目录 一、单例设计模式&#xff08;1&#xff09; 设计模式概述&#xff08;2&#xff09; 何为单例模式&#xff08;3&#xff09; 实现思路&#xff08;4&#xff09; 单例模式的两种实现方式1. 饿汉式2. 懒汉式3. 饿汉式 vs 懒汉式 &#xff08;5&#xff09; 单例模式的…

SQL零基础入门教程,贼拉详细!贼拉简单! 速通数据库期末考!(九)

UNION ALL UNION ALL 用于合并两个或多个 SELECT 语句的结果。 请注意&#xff0c;UNION ALL 合并的每个 SELECT 语句必须是查询相同数量&#xff0c;相同数据类型的字段&#xff0c;且顺序也必须一致。另外结果集中的列名总是等于 UNION ALL 中第一个 SELECT 语句中的列名。 …

PyQt(学习笔记)

学习资料来源&#xff1a; PyQt快速入门——b站王铭东老师 PyQt&#xff08;学习笔记&#xff09; Pycharm环境准备运行第一个程序QPushButtonQLabelQLineEdit调整窗口大小、位置、图标布局信号与槽PyQt引入多线程 Pycharm环境准备 新建环境——添加PyQt5模块——验证版本 如果…

视频封面:从视频中提取封面,轻松制作吸引人的视频

在当今的数字时代&#xff0c;视频已成为人们获取信息、娱乐和交流的重要方式。一个吸引人的视频封面往往能抓住眼球&#xff0c;提高点击率和观看率。今天将介绍如何从视频中提取封面&#xff0c;轻松制作吸引人的视频封面。 一、准备素材选择合适的视频片段 首先&#xff0…