MinGW/GCC延迟加载DLL的等效方法?

6

我正在尝试将一些旧的MSVC C++代码移植到MinGW/GCC。

其中一个问题是该项目在不总是使用某些函数,且正确的dll在运行时才能找到时,大量依赖于/DelayLoad选项。

在MinGW/GCC中是否有类似的选项?

此代码针对Windows平台。

3个回答

7

我想补充一点,尽管延迟加载DLL似乎是Windows操作系统的一部分,但它们实际上是由链接器生成的小存根来实现的。至少以前是这样的。因此,在Windows操作系统级别上没有正式的“延迟加载”概念。这是一种基于链接器生成的二进制代码约定。


1
并不是只有 Windows 才能实现延迟加载,其他操作系统也可以以同样的方式实现。 - yugr
1
现在已经有了,自从Windows 10。请参阅QueryOptionalDelayLoadedAPI - MSalters

4
在 Unix-like 系统上,对于 elf 目标文件,你可以使用 ld(MinGW 也使用该链接器) 指定 -z lazy 选项(默认情况下即为 lazy 链接)。
据我所知,在 Windows 上的 i386 PE 目标文件中没有明确的懒惰链接选项。我找不到任何可用选项的文档。

非常不幸。我必须想出某种解决方法。感谢您的帮助! - Ryan Stecker
5
我不认为这是正确的答案。-z lazy 使得符号解析被延迟,但共享库总是被加载。/DELAYLOAD 启用延迟链接,即延迟加载库直到其中一个函数被调用(Solaris 拥有此功能,但它并未出现在 Glibc 中,因为 Drepper^W^W 由于某种原因)。 - yugr
1
@yugr 是正确的,gcc 只对符号进行延迟加载(这也是默认值),并且它将在启动时加载库,根本不涵盖 MSVC 的 /DELAYLOAD 目的。 - ceztko

2
您可以使用--output-delaylib参数来创建延迟加载的导入库。然后,您可以链接到生成的导入库以延迟加载DLL。
例如,如果您想要延迟加载Windows DLL version.dll,它导出了GetFileVersionInfoSizeW,则可以通过以下方式进行懒加载。首先,在version.def文件中定义我们要调用的函数:
EXPORTS
 GetFileVersionInfoSizeW

然后我们可以使用 dlltool 创建一个延迟加载的导入库:
dlltool --input-def version.def --output-delaylib version.lib --dllname version.dll

连接时,请使用生成的 version.lib 文件:
gcc -o test test.c -lversion -L .

这个例子的完整版本可以在我的GitHub上找到。
有趣的事实是:在提出这个问题时,该功能很可能还没有在发布的软件中可用。该功能是在提问之前三个月提交的。

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