发布时间:2023-04-30 10:00
动态库的生成(重点)
静态库的生成(重点)
库的使用(重点)
链接的时候使用库(重点)
运行的时候使用库(重点)
查看当前程序所依赖的库(了解)
本节课重要的原因:
以后的使用大多数都是使用现成的动态库和静态库,在本文章我们以加法add()函数建一个动态库和静态库,分过程讲解动态库和静态库的生成与动态库使用。,使用动态库讲述链接与运行加载库的过程(静态库的链接与动态库一样,不一样的是静态库运行时不需加载静态库)
动态运行的时候加载,加载到内存之后,需要在多个程序中都要去使用。这样我们需要理解一个程序的运行需要将内存中的代码和数据映射到进程虚拟地址空间中映射到虚拟地址空间去才能访问,这个动态库需要映射到各个库独立的虚拟地址空间中去才能被访问,生成库的时候有自己的信息,映射的时候 ,无法保证每个程序都将它映射到虚拟地址空间中的同一位置,所以动态库就不能用于每个程序,所以要加上fPIC 产生位置无关的代码,库映射到虚拟地址空间的同一位置,每一个函数进行计算的时候拿偏移量+首地址就能得到,便于映射到每一个程序中(了解)。
在这里 我们把加法函数建一个动态库和静态库去使用和讲解
新建一个add.c文件
int add(int a,int b)
{
return a+b;
}
在新建一个main.c文件
1 #include
2 int main ()
3 {
4
5 printf("%d".add(2,3));
6 return 0;
7 }
可以看到我们的文件中已经存在动态库libadd.so
可以看到我们的文件当中已经存在静态库libadd.a
查看静态库的汇编代码:objdump -S libadd.a
对比与总结:动态库的汇编指令比较多,其中加载的比较多, 有符号表,注册信息,代码信息(动态库的汇编指令还没有罗列完,还有很多)
在讲库的使用之前先要弄清楚
为什么链接的时候要使用库呢???
不能生成可执行文件,因为没有add函数的声明
接下来我们看:
运行错误没有找到add有关的动态库,这是为什么呢???
因为动态库和静态库链接的时候都是到指定位置下找动态库和静态库的位置。所以我们要把库放在指定路径下。当然链接也有其它的方法,我们往下进行浏览
1、将库文件放置在指定的路径下
指定命令 sudo cp libchild.so /lib64/
重新编译 gcc -o main main.o -lchild 就好了
运行成功(add(2,3) = 5)但是放到指定路径下会污染系统目录,使用完记得在路径下删除文件(以便我们验证后面的方法)
记得删除系统目录中的:sudo rm -rf /lib64/libchild.so
删除完毕系统指定目录下的libadd.so,再次编译就生成不了可执行文件main了。
2、设置LIBRARY_PATH环境变量
export LIBRARY_PATH=${LIBRARY_PATH}: ./ (加上{} 表示变量)
echo $LIBRARY_PATH 查看环境变量LIBRARY_PATH内容
重新编译 gcc -o main main.o -ladd,但此时还是无法运行!接下来还要讲运行时加载动态库
unset LIBARY_PATH 删除环境变量就编译不通过
3、通过gcc -L选项设置链接库的默认搜索路径 gcc -o main main.o -L ./ -ladd(常用的方法)
注意:
-l(小L) : 指定连接库名称(去掉lib().so,只要()中间的名字)
-L:指定库的链接搜索路径(./在当前文件下)
但是和设置环境变量的使用一样,生成可执行程序后,运行不了程序;但是将库放置在指定文件夹(/lib64/)下就可以运行。接下来我们讲运行时使用库.
运行的时候使用的库是动态链接生成的动态库。静态链接运行的时候不需要加载库,只有动态库才会在运行的时候加载库
./main 运行不了
1、将库文件放置到指定的路径下
和链接的时候使用库用法一样,将libadd.so 放置指定路径下就可以运行了 。sudo cp libchild.so /lib64/。所以将动态库放置在这个路径下,可以直接成main并执行程序
2、设置LD_LIBRARY_PATH环境变量(用法同链接时一样)
gcc 默认链接的是动态库,-l(小L)加上库的名称的话默认是先找动态库,若没有动态库,则就是找静态库。 当一个路径下(或第三方库)既有动态库又有静态库,想链接静态库的时候,拿出来放置到另一路径下。
ldd main 查看main程序所依赖的动态库
not found 没有找到所依赖的动态库。
只设置了链接时的时候使用了库(LIBRARY_PATH)
运行的时候使用库没有设置(LD_LIBRARY_PATH)
所以ldd main中 libadd.so还是没有找到
运行的时候链接库 ,此时就可以找到依赖的动态库了!