面试 | Linux 下的动态链接库问题

面试 | Linux 下的动态链接库问题,第1张

在 Linux 开发时,我们经常会看到一些形如 xxx.so 的名称出现,其中 so 是 Shared Object 的缩写,即可以共享的目标文件,也就是我们所称为的动态链接库,和在 Windows 下大家玩 游戏 时遇到的 xxx.dll 错误中的文件是一个类型的。

面试中经常会问到以下问题:

库是写好的现有的,成熟的,可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。本质上来说库是一种可执行代码的二进制形式,可以被 *** 作系统载入内存执行。

库有两种:

在一个程序的编译过程中,分为以下几个步骤: 预处理 编译 汇编 链接 。本文中讨论的链接库就是针对最后一个步骤「链接」而言的。

动态库和静态库的区别

左图为静态链接库,右图为动态链接库

对于静态链接库而言在链接阶段,会将汇编生成的「目标文件.o」与引用到的库一起链接打包到可执行文件中。因此对应的链接方式称为静态链接:

静态链接可以理解为最后生成了一个「单文件免安装绿色版」的程序,优点在于移植的时候只需要移动这一个文件,缺点在于文件体积非常大,为了解决这样的问题,就有了动态链接库。动态链接库在程序编译时并不会被连接到目标代码中,而是在程序运行时才被载入。

动态库连接到系统空间,如果多个程序连接了同一个库,那么只需要一份,优点在于编译程序的时候不会将对应的库文件全部打包在生成的程序中,而是保留了到对应库的链接,缺点就是移植的时候如果只移动了对应的程序没有安装相关的库的话,就会看到类似以下喜闻乐见的结果了。

在 Linux 下一个动态库有y三个不同名字的文件组成:

当程序在内部列出所需要的链接库时,仅仅使用 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.表示搜索要链接的库文件时包含当前路径。

但是这样直接运行的话,会出现一个错误:

由于 Linux 是通过/etc/ld.so.cache文件搜寻要链接的动态库的,而 /etc/ld.so.cache 是 ldconfig 程序读取 /etc/ld.so.conf 文件生成的,本次使用的动态库 libmax.so 并不在对应的目录下,就会导致程序无法找到对应的动态链接库,这样我们的解决方法有二:

小结

​动态链接库是各个系统中的一个重要的组成部分且在 Linux 开发相关领域中尤为重要,也是一个面试的高频考点,除了动态链接库以外,还有以下相关知识也是高频考点,在面试前一定要准备好:

本文作者:Nova Kwok

动态链接库是电脑系统中的一些非常重要的,但是又不是必须时刻使用的一些常用功能的代码集合。这些功能对于电脑系统来说很重要,没有他们的协助,将会导致部分的功能无法实现,因此需要能够在需要使用它们的时候可以快速的调入系统内存中提供使用。但是如果把它时刻都放在电脑内存中又不现实,两个方面原因:第一就是这些库都非常的多,全部放入内存中的话,那么会导致电脑的内存严重不足,无法完成相关的导入工作。第二就是这部分的功能使用并不是非常的频繁,也不会影响到电脑的基本功能,如果全部一直放到内存中,也影响了内存的利用率。因此最好的方法就是将它变成硬盘上的一个一个的文件,需要使用的时候,根据需要从硬盘调取。这个放置这些特定功能的电脑文件,就是系统的动态链接库。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/8631757.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-19
下一篇 2023-04-19

发表评论

登录后才能评论

评论列表(0条)

保存