静态库、动态库比较与制作

静态库、动态库比较与制作

静态库与动态库比较

  • 文件名:在unix中静态库一般以.a结尾,动态库一般以.so结尾

  • 静态库:静态库和源码一起被打包到最终的可执行文件(ELF),节约了编译时间,最后得到的可执行文件体积大,但是速度快

  • 动态库:动态库不和源码一起被打包,执行到库函数时会去动态寻找调用动态库中的库函数,可执行文件体积小,但是速度慢(现在二者速度差异减少)

静态库

制作方法

要制作一个静态库,或将目标代码加入到已存在的静态库中,可以使用以下命令:

ar rcs libmylib.a file1.o
  1. 准备好源码对应的目标.o文件

image

  1. 制作静态库

ar rcs libmymath.a add.o div1.o sub.o

得到libmymath.a静态库,一个ar架构的文件

image

如何使用

一般的,制作好的动态库必须与对应的头文件一起提供者给开发者

image

将目标代码与静态库一起编译到一起使用:

gcc main.c libmymath.a -o main

生成ELF文件正常使用,生成的文件大小相对较大:

image

动态库

上一节静态库的制作需要用若干.o文件,动态库由于在程序中被用到响应的库函数,才会被加载到内存,然后去寻址执行相应函数,因此动态库需要生成"与位置无关的代码"

地址回填

image

程序中要使用动态库中的函数,不能依赖main在做地址偏移,也就是上图中,如果func1和func2动态库的库函数,则无法找到相应的地址,因为执行的ELF文件,没有经过.o->ELF的地址回填步骤,所以动态库需要生成与位置无关的代码-fPIC

静态库与动态库函数反汇编比较——延迟绑定

objdump -dS ELF查看反汇编

动态库加载到内存,@plt被替换掉,动态库函数才会有地址——延迟绑定

image

动态库制作

生成与位置无关的代码—— -fPIC

制作.o时,增加参数,-fPIC

gcc -c add.c add.o -fPIC

image

gcc -share 制作动态库.so

gcc -shared -o libmylib.so add.o sub.o div1.o

image

编译ELF时,指定所用的动态库 -l: 指定库名 -L: 指定库路径

gcc main.c -o main -lmymath -L./lib

image

动态库加载错误及解决办法

根据上一节的步骤,可以利用源码和动态库生成可执行文件,运行时会报下面的错误:

image

链接器:工作于链接阶段,工作时需要-l -L

动态链接器:工作于程序运行阶段,工作时需要提供动态库所在目录位置

二者无关,非说有关系,那就是张三和张三丰的关系~

【加载错误原因/解决办法】

总之,动态库在工作时,动态链接器会去几个固定位置找.so的位置:

  1. 环境变量:export LD_LIBRARY_PATH=./lib,环境变量只能使一个终端进程生效,临时办法

  2. 配置文件:

    在home目录下的.bashrc中添加export LD_LIBRARY_PATH=lib的绝对路径,然后source .bashrc,非临时办法

    image

  3. xx.so放到系统库目录下:/lib,不建议这么做

ldd指令查看动态库依赖】

如果xx.so加载失败,=>后面的动态库路径是空

image

  1. 修改/etc/ld.so.conf配置文件

​ 【1】sudo vi /etc/ld.so.conf,添加你的动态库路径

​ 【2】sudo ldcofig -v ,更新查找动态块的路径

​ 【3】测试是否好了

posted @ 2024-03-24 16:43  胖白白  阅读(6)  评论(0编辑  收藏  举报