当前位置: 首页 > news >正文

动态库与ELF加载

目录

动态库

ELF格式

ELF和后缀的区别

什么是目标文件

ELF文件中的地址--虚拟地址

动静态库和可执行文件

动态库ELF加载

为什么编译时静态库需要指定库?而运行时不需要指定库的,但是动态库需要呢?

总结:


动态库

动态库制作需要的.o文件需要使用选项fPIC

g++ -c -fPIC test.cc -o test

制作成动态库需要的是指令是g++ -shared -o libmylib.so test.o

运行时查找动态库

动态库链接分为编译和运行

gcc/g++的时候也是链接了的,只不过没有拷贝到可执行程序中,而是建立联系,等待可执行程序执行时才会再次查找动态库中的具体内容

这也是动态库和静态库的区别,静态库在链接的时候会把代码拷贝到可执行程序中,这样的话其实静态库怎样变都不会影响可执行程序了,因为可执行程序中有备份;

但是动态库不是会将库的内容拷贝到可执行程序中而是运行时需要加载到内存中的,是实时加载的,所以动态库改变也会影响到可执行程序

运行时查找是默认系统路径中查找的?

为什么是在默认系统路径,为什么是默认的,因为在环境变量中;

LD_LABRARY_PATH;

对环境变量赋值 export LD_LABRARY_PATH=绝对路径

打印环境变量---> echo $LD_LABRARY_PATH

ELF格式

ELF 是可执行与可链接格式,是一种通用的目标文件格式。它能让程序在不同系统上方便地编译、链接和运行。ELF 文件里有代码段、数据段这些不同的段,还有符号表、重定位信息等。代码段存程序指令,数据段放程序用到的数据。符号表记录函数、变量等的信息,重定位信息帮链接器确定地址。它的结构清晰,能很好地支持程序的加载和执行呢。

ELF和后缀的区别

ELF 主要是一种文件格式规范,跟文件后缀没必然联系。它定义了目标文件、可执行文件等的结构和内容组织方式。像.o 文件、可执行文件,还有共享库等都可以是 ELF 格式。虽然常见的 C 语言源文件有.c、.cpp 等后缀,但经过编译链接生成的目标文件和可执行程序如果符合 ELF 规范,那就是 ELF 格式的文件啦,跟源文件后缀没关系哦。

什么是目标文件

编译过程中的.o文件和可执行程序文件都是目标文件。

可执行程序其实就是把多个.o文件经过链接整合起来的,本质上还是多个.o文件,内容格式就是ELF格式

ELF文件中的地址--虚拟地址

经过编译形成ELF格式的目标文件后,这个时候其实就是对进程的虚拟地址进行了规划,虽然还没有产生进程,也没有被分配对应的物理空间,这算是一个“蓝图”;

然后我们执行可执行程序的时候,进程被创建操作系统会分配给该进程一个大块的物理内存空间,然后一遍执行一遍维护页表,建立虚拟地址和物理地址的映射关系,然后再对应的物理内存上加载数据;

在程序执行完毕后,就会释放掉物理内存和页表(这都是在物理空间中的),如果没有对其他文件操作,那么就没有什么数据保留下来,可执行程序也会在内存中释放掉,但是磁盘上保留着文件,所以下次可以在使用

动静态库和可执行文件

动静态库本质就是对目标文件打包了,内部的各个目标文件没有建立联系,而可执行程序他是把目标文件建立了链接,其中的目标文件都是有联系的;但本质他们都是目标文件,二进制指令;

动态库ELF加载

通常情况下,加载动态库时,系统会先把整个库加载到内存,但并不会一次性把所有函数都加载到可执行程序中。只有当程序执行到需要调用动态库中某个函数的位置时,才会真正把这个函数的代码加载到可执行程序的地址空间里,这就是所谓的 “按需加载”。这样做可以有效节省内存资源,特别是对于那些包含很多函数,但程序只用到其中一部分的动态库来说,优势很明显。不过,不同的操作系统和动态链接器在具体实现上可能会有一些细微差别,但总体思路是类似的。

为什么编译时静态库需要指定库?而运行时不需要指定库的,但是动态库需要呢?

编译的过程是对语法检查,而不涉及内存逻辑上的检查,所以我们的代码中使用到了别的第三方库文件的时候,我们使用了对应文件中的函数和变量声明,在形成可执行文件的过程中其实就会对当前的文件进行语法检查,但是不会检查其他文件中的函数实现;


运行时已经生成了可执行程序,这个时候如果报错就是逻辑上的错误,只能针对源代码再次编译了;

而之所以静态库不需要再运行时指明库,那是因为在链接的过程中,其实已经把静态库的内容镶嵌到了可执行程序中;可执行程序执行中可以直接使用;

那为什么动态库就需要指明库路径呢?

那是因为动态库并没有把内容放到可执行程序中,链接过程中,他只是和可执行程序建立了“羁绊”,可执行程序可以使用动态库内容,需要的时候就会加载到内存中,这个就是ELF动态加载,所以动态库实时使用,随用随拿的,如果动态发生更改,那么可执行程序就会收到影响;

总结:

所以链接时,需要的是库中的内容函数实现,动态库因为没有在可执行程序中,所以需要指定查找;

而编译时需要的是检查的库内容,也就是头文件,所以如果我们只是为了得到.o目标文件那么是不需要指明动静态库路径的;

我们平时是直接从源文件直接生成可执行程序,所以需要头文件和动静态库同时使用;如果是动态库那么就还需要注意运行时查找动态库路径;---环境变量配置

相关文章:

  • 白皮解读:数据流通关键技术白皮书【附全文阅读】
  • 【KWDB 创作者计划】_KWDB事务管理模块实现原理
  • Three.js支持模型格式区别、建议
  • 前端面经-VUE3篇(二)--vue3组件知识(二)依赖注入、异步组件、生命周期、组合式函数、插件
  • 3.0/Q1,Charls最新文章解读
  • yolov5 train笔记4 roboflow
  • Linux《进程概念(下)》
  • 射频指标互调与交调简略
  • RPG7.准备GAS的工作
  • Linux 的 epoll 与 Windows 的 IOCP 详解
  • 重塑数学边界:人工智能如何引领数学研究的新纪元
  • Transformer架构:基于自注意力机制推动NLP革命性突破
  • 有机玻璃材质数据采集活性炭吸附气体中二氧化硫实验装置
  • 别样健康养生之道
  • 【Arthas】火焰图优化应用CPU(问题原因:获取调用栈)
  • sonar-scanner在扫描JAVA项目时为什么需要感知.class文件
  • FPGA DDR4多通道管理控制器设计
  • 影楼精修-露齿笑算法解析
  • Python Cookbook-6.18 用__init__参数自动初始化实例变量
  • Pillow 玩图术:轻松获取图片尺寸和颜色模式
  • 福建两名厅级干部履新,张文胜已任省委省直机关工委副书记
  • 中国企业转口贸易破局之道:出口国多元化,内外贸一体化
  • 中虎跳峡封闭仍有游客逆行打卡,景区:专人值守防意外
  • 少数人的奢侈品还是所有人的必需品:我们如何解构创造力?
  • 美法官裁定特朗普援引战时法律驱逐黑帮违法,系首次永久性驳回
  • 女冰队长于柏巍,拒绝被年龄定义