如何将动态链接库转换为静态链接库?

22

我编写了一个名为helloworld.exe的程序,该程序依赖于a.dll。但我没有a.dll的源代码,它是一个动态链接库。我该如何将它转换为静态库,以便将其链接到helloworld.exe中?

8个回答

15

抱歉,没有直接的方法可以做到这一点。DLL是一个完全链接的可执行格式文件,而静态库是由多个单独的目标文件组合而成。通过一些努力,您可以将静态库转换为DLL,但反过来做则非常困难(姑且这么说吧)。


1
+1 给原问题的唯一正确答案。 (我的回答只是一个解决方法) - Billy ONeal
不仅如此,对于那些不是可执行文件而是像它们的名称一样“动态链接库”的dll,有工具可以将.lib和.dll转换为.a(静态库)。我甚至在某些情况下成功地通过简单地重命名(是的,我不知道为什么这会起作用)并链接到库来使其工作(尽管它所依赖的库仍然是动态加载的)。 - chacham15

5
正如Jerry所说,你不能直接这样做。但是,你可以将你的程序打包成类似于自解压缩RAR文件的形式,其中包括了DLL作为单个EXE的一部分,它会自动将EXE和相关的DLL文件提取到临时文件夹并启动主程序。

2

不,这是可能的。例如,有一个称为dlltolib的工具可以实现。


2
实际上,描述中非常明确地说明它只创建一个导入库:“一个 .NET 命令行应用程序,从目标动态链接库 (.dll) 生成一个导入库 (.lib)。” - Joe
3
为什么你假设我在谈论并且给我的回答点了个踩呢,@Joe?一个快速的谷歌搜索会告诉你http://www.binary-soft.com/dll2lib/dll2lib.htm,它在第一行就说“将DLL文件转换为等效的静态库。” - chacham15
2
“a quick google search” 带我找到了与 Mike 相同的 Github 项目。评论也是关于 Mike 提到的软件。你的回答不太清晰,特别是没有包含一个可以找到该工具的链接,所以我给你点了个踩。但现在你已经改正了,所以我会取消踩赞。 - Joe
1
无论如何,这个链接的工具似乎并不太有用,因为它只支持32位,这在当今已经相当受限制了。 - Joe
1
此外,自2019年9月8日起,binary-soft的dll2lib工具的单用户开发许可证现在为100美元。 - BugSquasher
@КонстантинВан 不是的,那个工具实际上是将dll转换,没有导入库。 - chacham15

1
也许问题是如何创建一个.LIB文件,以允许静态链接到.DLL。以下是实现此目的的示例命令:
set DUMPBIN="C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\Hostx86\x86\dumpbin.exe"
set LIBX="C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\Hostx86\x86\lib.exe"
set IN="\MyFolder\MyDll.dll"
set DEF="\MyFolder\MyDll.def"
set LIB="\MyFolder\MyDll.lib"

:: [1] run dumpbin
%DUMPBIN% /EXPORTS /NOLOGO /OUT:%DEF% %IN%

:: [2] edit .DEF file to look proper
:: [3] run LIB
%LIBX% /DEF:%DEF% /OUT:%LIB%

0
长话短说,从技术上讲是可能的。但是,事实并不像看起来那么简单(仅仅从COFF文件的特征中删除IMAGE_FILE_DLL)。
例如,DLL可以选择性地指定一个入口点函数,每当进程或线程加载或卸载DLL时自动调用该函数。它可以用于执行简单的初始化和清理任务。而在LIB中是无法实现这样的功能的。
任何声称可以从DLL生成LIB的工具只是生成了一个静态绑定,只链接到该DLL的函数声明。你不能删除DLL并仅使用LIB - 这是行不通的。

0
在Windows上,如果您有相应的def文件,您可以获取lib文件来运行您的程序。您可以使用Visual Studio的命令提示窗口获取lib文件。命令行如下:lib /def:XXX.def /machine:x64(或x86以获取32位lib)/out:XXX.lib。您需要确保def文件和dll文件在同一个文件夹中,并且您已更改目录到该文件夹中。

2
还有,那是一个导入库,它是DLL的静态加载器。 - Константин Ван

-1

-4

我对至少一个(据说很受欢迎的?)答案中缺乏理解感到非常震惊。

我从头开始编写了链接器,每一行代码都是我自己写的。我知道关于DLL的所有信息。

DLL包含比lib更多的信息,并且它确实包含lib包含的绝对所有内容。每一项都有。

要将dll转换为lib,您可以按照以下精心编写的文章中提供的简单步骤进行操作。

https://adrianhenke.wordpress.com/2008/12/05/create-lib-file-from-dll/

(我不是Adrian Henke,只是提供信息)

所描述的过程允许您直接从DLL创建一个库,而无需使用DEF文件。实际上,它甚至允许您从DLL创建DEF文件,因为DLL包含了所有这些信息。

我可以保证它完美地工作,因为我实际上在DLL上运行了完全相同的过程并检查了结果。库是正确的,并且将允许您进行链接。

哦,顺便说一下,将库转换为DLL是绝对、完全、彻底不可能的。


1
不知道为什么会有负评,但是你的链接是404。adrianhenke.wordpress.com已被用户删除。 - BugSquasher
5
和其他答案一样,这似乎只会创建一个导入的.lib文件,在运行时仍需要.dll文件。真正的静态.lib文件将包含代码。 - jpa
1
不需要这种态度!这是一个存档副本,原链接已经失效。正如jpa所说,该链接仅说明如何创建导入库,而不是包含代码的完整.lib文件。像你一样,我并没有明显看出从.dll转换为.lib会有什么缺失,除了安排调用它的DllMain需要一些努力,但我认为你对自己的说法过于自信,特别是因为你还没有提出实际的解决方案。 - Arthur Tacca
我想知道为什么有这么多负面评价,我猜是因为你没有提供一个容易CTRL-C + CTRL-V的东西。这完全是可能的,我只需要反汇编一个DLL,它会给我“.s”,然后再用标准工具“编译”成“.a”。很容易做到。 - Luiz Felipe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接