返回

Linux翻译教程:执行对象文件(三)

前端

外部库的问题

在上一篇文章中,我们学习了如何处理对象文件中的重定位,以便正确地连接代码中的内部依赖关系。在这篇文章中,我们将研究如果代码有外部依赖关系会发生什么--也就是说,它试图调用外部函数或使用外部变量。

当代码有外部依赖关系时,链接器会尝试在链接过程中找到这些依赖项。如果链接器找不到这些依赖项,它就会报错。例如,如果我们有一个代码文件main.c,它调用了printf()函数,那么在链接时,链接器会尝试找到printf()函数的实现。如果链接器找不到printf()函数的实现,它就会报错。

为了解决这个问题,我们需要告诉链接器在哪里可以找到这些外部依赖项。我们可以通过两种方式来做到这一点:动态链接和静态链接。

动态链接

动态链接是一种在运行时加载外部依赖项的方式。当我们使用动态链接时,链接器不会将外部依赖项的代码包含在最终的可执行文件中。相反,它会在可执行文件中包含一个指向外部依赖项的共享库的引用。当程序运行时,操作系统会自动加载这些共享库并将其链接到程序。

动态链接的优点是它可以节省空间和内存。因为共享库只会被加载一次,所以多个程序可以同时使用它。这可以节省磁盘空间和内存。此外,动态链接还可以简化程序的更新。因为当共享库被更新时,所有使用它的程序都会自动更新。

动态链接的缺点是它可能会导致性能下降。因为当程序调用外部函数时,操作系统需要花费一些时间来加载共享库并将其链接到程序。此外,动态链接还会增加程序的安全性风险。因为如果共享库被恶意软件感染,那么所有使用它的程序都会受到感染。

静态链接

静态链接是一种在链接时将外部依赖项的代码包含在最终的可执行文件中。当我们使用静态链接时,链接器会将外部依赖项的代码复制到可执行文件中。这样,当程序运行时,它就不需要加载共享库了。

静态链接的优点是它可以提高程序的性能。因为当程序调用外部函数时,操作系统不需要花费时间来加载共享库并将其链接到程序。此外,静态链接还可以提高程序的安全性。因为当程序被执行时,它不需要加载任何外部库,所以恶意软件就无法感染程序。

静态链接的缺点是它会增加可执行文件的大小。因为外部依赖项的代码会被复制到可执行文件中。此外,静态链接还会使程序的更新变得更加困难。因为当外部依赖项被更新时,所有使用它的程序都必须重新链接。

如何将外部库链接到代码

现在我们已经了解了动态链接和静态链接的区别,我们可以学习如何将外部库链接到代码。

要将外部库链接到代码,我们可以使用gcc编译器的-l选项。-l选项告诉gcc编译器在链接时要链接指定的库。例如,要将printf()函数所在的libc库链接到代码,我们可以使用以下命令:

gcc -o main main.c -lc

总结

在本文中,我们学习了如何处理外部库的问题。我们还学习了动态链接和静态链接的区别。最后,我们学习了如何将外部库链接到代码。