动态库和静态库

区别

假设库的大小是500M
静态库的时候,是把库都编译进程序中,每一个程序就多一个500M,因为实在自己程序里,所以调用的时候速度快
动态库是所有程序共享这个一个库,动态库会先保存在内存中,程序需要的时候会调用,比在自己的代码里多了一个进入内存的操作,所以速度比静态库慢

  • 静态库适用于对空间需求低,速度需求高的场景,比如操作系统的启动
  • 动态库适用于对空间要求高,时间要求低的场景,比如数据库

静态库的制作和使用

静态库制作代码

ar rcs libmylib.a file.o

前两个命令是固定的,第二个c是不存在就创建的意思,第三个是制作的静态库的名字,第四个是输出文件注意:静态库的名字必须以lib开头,mylib为自己的名字,.a为后缀
例子:
首先建立一个add.c, sub.c, div1.cimage输出.o文件记得加-cimageimage
再移动一下image
再也一个测试文件image注意:编译时候的错误会出现行号,没有出现行号是链接时候的错误imageimage
如下图可知,编译出来的文件比较大image
gcc的时候,注意.c文件在前,静态库在后
注意上面有警告,隐式声明,出现在编译阶段。当没有函数定义或没有函数声明的情况下,编译器会作隐式声明。但是编译器一般只会声明 int 函数名(int, int )这种,出现void * 函数名的时候就不行了,容易出现错误
上述问题解决办法就是在test.c中隐式声明三个函数:
int add(int, int)
int sub(int, int)
int div1(int, int)
再但是:上面操作是我自己做的静态库,在网上下的时候,并不知道函数名字,所以一般静态库制作者会再制作一个头文件声明这些函数,在使用的时候调用头文件即可。image

image

动态库的制作和使用

第一步同静态库,也是将.c文件生成.o文件。(生成与位置无关的代码)注意:动态库里面的函数,只有当调用程序执行到动态库的函数位置上时才会调用动态库,即调用的动态库的函数地址是动态在变的,因为动态库在变
地址回填:image
动态库的函数在没调用之前是没有地址的,使用反汇编
objdump -dS test > outimage
由图可知,是根军@plt来绑定地址的。

  1. 所以生成动态库的时候使用
gcc -c add.c -o add.o -fPIC

这样生成的add里面的函数都是plt地址的
2. 再使用

gcc -shared -o lib名字.so add.o sub.o div1.o

制作动态库
3. 使用动态库:编译可执行文件时要指定动态库
-l, 用来指定库名
-L, 用来指定库路径

gcc test.c -o test.out -l mylib -L ./lib

注意使用的时候要去掉lib和.soimage

image
如图所示出错了。
出错原因:链接器: 工作与链接阶段,在a.out文件执行前,工作的时候需要l和L动态链接器: 工作在程序运行阶段,需要提供程序动态链接库所在位置,如果没有提供,就会去LD_LIBRARY_PATH的环境变量找image
但是环境变量是进程的概念,用export之后,打开新的进程就没了。永久生效~./bashrc,更改,然后source 它或者. 执行或者重启,建议使用永久路径
第三种方法,也可以直接复制到./lib下ldd a.out: 查看可执行文件的动态库路径
第四种方法,vim /etc/ld.so.conf
加入动态库路径,再输入 sudo ldconfig -v加载一下

数据段合并

image链接的时候会合并代码段和制度数据段,合并的好处是为了节省空间, 通过MMU映射,4kb是一页(磁盘是512k),这两段比较小,用不了8k,所以合并。
。bss和.data也会合并

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值