Unix/Linux 环境中的动态链接类型

Unix/Linux 环境中的动态链接类型

创建 Windows 静态库时,我们只需创建一个 .lib 文件,该文件应包含在链接器路径中。

创建 Windows 共享库时,除了 .dll 之外,我们还生成一个 .lib 文件。此 lib 文件包含库公开的 API 的签名。

有两种方法可以使用这个库

  1. 我们可以直接在项目中引用库 API,并在链接器属性中添加 .lib 文件的路径。有人称其为静态链接动态库
  2. 或者我们可以在运行时显式加载动态库。在这种情况下,我们不需要为链接器指定lib文件路径。称之为动态链接的动态库。

我的问题是 Linux 上的共享库也有类似的东西吗?或者只是静态库(.a)和共享库(.so)?

我知道如何使用 gcc -l 选项在 Linux 上包含静态库。我们是否可以使用相同的选项来包含动态库 (.so)?

答案1

我不能说我理解什么是“静态链接的动态库”,也不知道有关库中包含的签名的任何信息(听起来很有趣:这是否意味着链接器能够检查参数中的类型不匹配以及链接处的返回类型)时间?ELF肯定没有这样的功能。)所以这个答案不会是从比较的角度来看。另外,由于您的问题非常广泛,因此答案将很肤浅。

是的,您可以创建静态库 ( .a) 或共享库 ( .so)。当链接器查找使用 请求的库时-l,如果两者都存在,它将优先选择共享库,除非使用诸如 之类的选项覆盖-static

当从源代码构建库时,只需将其构建为静态库 ( .a) 或共享库 ( .so),而不是两者都构建。尽管如此,还是有相当多的包的构建脚本被设置为构建两个版本(这需要编译两次,一次使用位置无关代码,一次不使用),以便让库的使用者选择链接哪个版本。

静态库的必要部分完全合并到构建的二进制文件中。无需.a在运行时提供该文件。相反,链接到二进制文件的共享库必须在运行时可用,尽管运行时动态链接器通常会在修改后的名称“soname”下搜索它(通常libsomething.so在链接时和libsomething.so.<integer>运行时) ),该功能允许同时在系统中安装 API 略有不同的多个不同版本的库。

在您的问题中,您还提到在运行时显式加载动态库。这通常是针对模块化应用程序或带有插件的应用程序完成的。在这种情况下,相关库(通常称为“模块”或“插件”)根本不与应用程序链接,并且构建时链接器对此一无所知。相反,应用程序开发人员必须编写代码来调用运行时动态链接器并要求它按文件名或完整路径名打开库。有时,要打开的模块的名称列在应用程序的配置文件中,或者有其他一些应用程序逻辑来决定需要或不需要哪些模块。

相关内容