在 Linux 开发时,咱们时常会看到一些形如 xxx.so 的名称呈现,其中 so 是 Shared Object 的缩写,便可以同享的目标文件,也就是咱们所称为的动态链接库,以及在 Windows 下大家玩游戏时遇到的 xxx.dll 过错中的文件是一个类型的。
面试中时常会问到下列问题:文章源自微观生活(93wg.com)微观生活-https://93wg.com/14570.html
如何创立一个动态库?文章源自微观生活(93wg.com)微观生活-https://93wg.com/14570.html
动态库文件的后缀名是什么?文章源自微观生活(93wg.com)微观生活-https://93wg.com/14570.html
如何使用一个动态库?文章源自微观生活(93wg.com)微观生活-https://93wg.com/14570.html
动态库的命名规范?文章源自微观生活(93wg.com)微观生活-https://93wg.com/14570.html
系统默许的动态库的查找路径?文章源自微观生活(93wg.com)微观生活-https://93wg.com/14570.html
动态库显示连接所使用的系统库是什么?文章源自微观生活(93wg.com)微观生活-https://93wg.com/14570.html
一、什么是库文章源自微观生活(93wg.com)微观生活-https://93wg.com/14570.html
库是写好的现有的,成熟的,可以复用的代码。现实中每一个程序都要依赖不少基础的底层库,不可能每一个人的代码都从零开始,因而库的存在乎义非同寻常。本色上来讲库是一种可执行代码的二进制情势,可以被操作系统载入内存执行。文章源自微观生活(93wg.com)微观生活-https://93wg.com/14570.html
库有两种:文章源自微观生活(93wg.com)微观生活-https://93wg.com/14570.html
静态库(.a、.lib)
动态库(.so、.dll)
在一个程序的编译进程中,分为下列几个步骤:预处理,编译,汇编,链接。
动态库以及静态库的区分
左图为静态链接库,右图为动态链接库
对于静态链接库而言在链接阶段,会将汇编生成的「目标文件.o」与引用到的库一块儿链接打包到可执行文件中。因而对应的链接方式称为静态链接:
静态链接库对函数库的链接是放在编译时代完成的。程序在运行时与函数库就没有了任何的联络。
它比较挥霍空间以及资源,由于所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件。
静态库对程序的更新以及发布也会带来麻烦。如果静态库更新了,所有使用它的利用程序都需要从新编译、部署、发布给用户。
静态链接可以理解为最后生成为了一个「单文件免安装绿色版」的程序,优点在于移植的时候只需要移动这一个文件,缺陷在于文件体积无比大,为了解决这样的问题,就有了动态链接库。动态链接库在程序编译时其实不会被连接到目标代码中,而是在程序运行时才被载入。
不同的利用程序如果调用相同的库,那么在内存里只需要有一份该同享库的实例,可以实现过程之间的资源同享。(因而动态库也称为同享库)规避了空间挥霍问题。
动态库在程序运行时才被载入,也解决了静态库对程序的更新、部署以及发布带来的麻烦。用户只需要更新动态库便可将一些程序进级变得简单,增量更新。
动态库连接到系统空间,如果多个程序连接了同一个库,那么只需要一份,优点在于编译程序的时候不会将对应的库文件全体打包在生成的程序中,而是保存了到对应库的链接,缺陷就是移植的时候如果只移动了对应的程序没有安装相关的库的话,就会看到相似下列脍炙人口的结果了。
在 Linux 下一个动态库有y三个不同名字的文件组成:
soname 文件
lib + 链接库名字 + .so + .版本号
real name 文件
lib + 链接库名字 + .so + .版本号.次版本号.发行号
linker name 文件
lib + 链接库名字 + .so
当程序在内部列出所需要的链接库时,仅仅使用 soname。当你创立一个链接库时,使用 real name。安装一个新的链接库时,把它复制到一个DLL文件夹里,然后运行程序 ldconfig。ldconfig 检查存在的 real name 文件,并且创立指向它符号链接 soname 文件。可能大家比较常见到的有 libsodium 等。
二、创立一个动态库
有了上面关于库的一些基础知识以后,咱们可以开始尝试创立一个动态库来供程序使用了。
比如咱们有一个求最大值的函数 max(int a,int b,int c) ,放在文件 max.c 中文件内容如下:
可以通过:
将其编译为同享库,-fPIC是编译选项,PIC是 Position Independent Code 的缩写,表示要生成位置无关的代码,这是动态库需要的特性; -shared是链接选项,告知 gcc 生成动态库而不是可执行文件。为了让用户知道咱们的动态库中有哪些接口可用,咱们需要编写对应的头文件,比如可以写一个 max.h :
设置一个驱动函数来测试咱们编写的动态库:
通过 gcc test.c -L. -lmax来生成 a.out,其中-lmax表示要链接 libmax.so,-L.表示搜寻要链接的库文件时包括当前路径。
同一目录下同时存在同名的动态库以及静态库,比如 libmax.so以及 libmax.a都在当前路径下,则 gcc 会优先链接动态库。
然而这样直接运行的话,会呈现一个过错:
因为 Linux 是通过/etc/ld.so.cache文件搜索要链接的动态库的,而 /etc/ld.so.cache 是 ldconfig 程序读取 /etc/ld.so.conf 文件生成的,本次使用的动态库 libmax.so 其实不在对应的目录下,就会致使程序没法找到对应的动态链接库,这样咱们的解决办法有二:
如果仅仅是本地使用,可以在编译后指定一个环境变量:LD_LIBRARY_PATH=. ./a.out ,这样程序会在本地寻觅
如果需要在系统层面同享这个库,可以把 libmax.so 所在的路径添加到 /etc/ld.so.conf 中,再以 root 权限运行 ldconfig 程序,更新 /etc/ld.so.cache
具体采取的办法因使用场景而异,如果仅仅是测试用处的话,可以直接使用添加环境变量的方式解决。
小结
动态链接库是各个系统中的一个重要的组成部份且在 Linux 开发相关领域中尤为重要,也是一个面试的高频考点,除了了动态链接库之外,还有下列相关知识也是高频考点,在面试前一定要筹备好:
Linux 下 make 与 makefile。用什么参数指定 makefile 文件?什么是默许的makefile 文件?
Linux 静态库的使用,如何创立一个静态库?如何使用一个静态库?静态库文件的后缀名是什么?静态库的命名规范?
以上就是微观生活(93wg.com)关于“面试 | Linux 下的动态链接库问题”的详细内容,希望对大家有所帮助!
评论