我们可以静态链接动态 C 库吗?

Posted

技术标签:

【中文标题】我们可以静态链接动态 C 库吗?【英文标题】:Can we link a dynamic C library statically? 【发布时间】:2015-10-16 13:03:19 【问题描述】:

我们知道,在链接静态库时,链接器会将相关代码从 .a 文件复制到可执行的二进制文件中。并且在链接动态库时,链接器只是将它在 .lib 文件(在 Windows 下)中找到的函数的地址复制到二进制文件中,而不复制函数本身。在运行时,操作系统加载dll,程序根据地址运行代码。问题是,我可以使用 .lib 文件和 dll 来静态链接动态库吗?链接器从 .lib 中读取地址,然后将相关代码从 dll 复制到二进制文件中。它应该工作,对吧?

【问题讨论】:

提醒一下,检查库是否为 LGPL。并在实际操作之前理清所有法律问题。 也许如果您编写自己的工具链来执行此操作,或者互联网上什至有一些东西可以尝试这样做,但肯定不会使用任何标准工具。 @MicroVirus 所以你认为这个想法是可能的? @yvbbrjdr 只是理论上,但我从来没有调查过这件事,所以我的想法没有多大分量。 @MicroVirus 好的。然后我将编写自己的工具链来进行实验。 【参考方案1】:

我不知道您的想法是否可以工作,但请注意——在 Windows 上,至少在 Visual Studio 上——静态库与 DLL 非常不同。

对于 VS,静态库基本上只是一个目标文件容器,也就是说,您有一个 .lib 文件,但该 .lib 文件只是编译器为其生成的所有 .obj 文件的容器项目。

这里重要的是静态库中的.objcode还没有经过链接阶段,没有链接器已经参与。

而 DLL(最终)是由链接器(从目标文件)生成的。

所以这里的问题实际上是工具链支持之一,因为 DLL 已经是链接器输出,我怀疑您是否可以让链接器将其 PE 代码直接重新链接到可执行文件中。

【讨论】:

重新链接是什么意思? @yvbbrjdr re-link 没有任何具体含义。只是链接器必须再次链接它已经链接过的内容。【参考方案2】:

如果您想在构建时而不是运行时链接 .dll 是的,可以使用与 .dll 对应的 .lib 文件来完成。确切的方法取决于您用于构建应用程序的内容。

在 Visual Studio 中,您首先在 Linker->Input 项目属性中添加 .lib 文件。

虽然这是静态链接,但它不会将 .dll 代码复制到您的可执行文件中;您仍然需要 .dll 来运行应用程序。

此外,如果 .dll 是您开发的东西和/或拥有源代码,则可以将其修改/重建为静态库并链接到您的可执行文件中(这样您就不会拥有单独的 .dll 文件)。

【讨论】:

你可能误解了我的意思。我的意思是放弃dll,将其代码复制到exe中。 我不相信使用 3rd 方 dll 是可能的。如果您有源代码,则只能将其重新编译为静态库。 技术和知识产权原因的结合。 dll 的关键在于能够改进/更新它,而无需调用/重新编译/更新所有使用它的程序。将其嵌入程序中会破坏该目的。它还允许受 IP 保护的 dll 可能在应用程序中以不可见的方式非法分发。 所以我说的不是这种方式是否违反目的或违反法律。我只是想知道这种方式是否可行。

以上是关于我们可以静态链接动态 C 库吗?的主要内容,如果未能解决你的问题,请参考以下文章

我们可以创建 Ghostscript 的静态库吗?

C语言 | 什么是静态链接库和动态链接库?

怎么编写Makefile生成静态库

用C语言写的程序能调用C++写的静态库吗

CGO静态库和动态库

CGO静态库和动态库