文章目录
- 接上篇完成blog
- 第三方库安装演示
- 动态库加载原理
- 一
- 二
- 三
- 四
接上篇完成blog
上篇链接
第三方库安装演示
sudo yum install -y ncurses-devel
下载完成之后
在系统目录下面一定能找到对应的头文件和库文件
此时使用第三方库:
编译之后按错误提示是对应的函数找不到,所以链接库文件,库的路径在系统目录下,此时不需要指出
执行结果:
动态库加载原理
上篇提到,动态库的编译要使用
gcc -fPIC -c xxx.c
-fPIC叫做与位置无关码
一
1.在linux下,可执行程序的格式叫做ELF格式(有规则的二进制格式).
二
2.程序没有被加载到内存,程序内部有地址吗? 有!!!
将程序编成二进制后,变量名,函数这些都不存在,都会变成相应的汇编操作
编译的时候,对代码进行编址,遵守虚拟地址空间
虚拟地址空间不仅是OS的概念,编译器在编译的时候,也会遵守这个规则,这样才能在加载的时候,进行从磁盘文件到内存的映射关系
虚拟地址空间更是一种标准
虚拟地址(逻辑地址) = 基地址+偏移量
在代码还没有被加载的时候,
对应的变量和代码就已经有了自己的虚拟地址空间
这也叫做逻辑地址,
即基地址+偏移量
0 +[0,FFFFFFFF]
这种起始偏移量为0的对可执行程序的编址方式叫做平坦模式
程序有代码区和数据区,
将代码区的起始地址放在寄存器
数据区的起始地址和偏移量是什么,也会记在里面
对于每个可执行程序形成一个段,起始地址和偏移量就是通过这样的方式去定位的
当代的linux应用了虚拟地址,所以采用平坦模式,这样通过偏移量就能确定代码区和数据区
程序在编址时就是将所有的代码封成对应的区域
三
3.绝对编址,相对编址
在内存中的一个程序
相对编址:
相对编址更适合对库中的函数形成地址
这些函数只要记住相对于库中的偏移量就能找到这个函数
所以fPIC也就来了,与位置无关码
适合平坦模式的可执行程序
绝对编址:
每次程序加载随机分配的地址
四
4.库被加载之后,要被映射到指定的使用了该库们的进程的地址空间的共享区部分,库要加载前可以放在共享区的任意位置,都能正常运行
静态库文件的链接
动态库文件的链接
再页表部分最终这个动态库也会与虚拟内存通过页表进行映射
像程序被加载到内存中,是随机分布的
库被加载到内存中也是随机分布
因为都可以通过页表映射找到对应的区域
很重要的一张图,由于限制只能放这么大,链接直达下载
未来,当有一个新进程被启动,也要加载使用这个库,加载这个库内的方法
对于已经加载的方法直接call调用,没有的方法,会将方法直接映射到共享区
然后进行对应的代码调用即可
同样一张图概括main函数的整个过程,链接直达下载
创作不易,有用请三连,谢谢支持~~~