在没有 .lib 的情况下,如何在 Windows 中直接链接到 DLL

问题描述

TinyCC 和 GCC 都支持无库链接支持直接链接到 DLL 文件有一段时间了(因为从 Win3.1 开始,lib 没有真正的用途)。但出于某种原因,在 Windows 中,Clang 坚持将 .dll 文件解释为 .lib 文件。根据 LLVM 的页面,这里 https://lld.llvm.org/windows_support.html,lld-link 确实支持直接 dll 链接,但实际上,我没有看到任何指定的方法。 (LLVM 10.0 和 11.0 也是如此)

明确地说,我指的不是使用 LoadLibraryGetProcAddress 手动加载。我指的是像这样调用编译器:

"C:\Program Files\mingw-w64\x86_64-8.1.0-win32-seh-rt_v6-rev0\mingw64\bin\gcc" -o rdtest.exe rdtest.c -lgdi32 -luser32 openvr_api.dll C:\windows\system32\opengl32.dll C:\windows\system32\msvcrt.dll

^^ 作品

"C:\Program Files\LLVM\bin\clang.exe" -fuse-ld=lld-link -v -o rdtest.exe rdtest.c -lgdi32 -luser32 openvr_api.dll C:\windows\system32\opengl32.dll C:\windows\system32\msvcrt.dll
[...]
1 warning generated.
 "C:\\Program Files\\LLVM\\bin\\lld-link" -out:rdtest.exe -defaultlib:libcmt "-libpath:C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Professional\\VC\\Tools\\MSVC\\14.28.29333\\lib\\x64" "-libpath:C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Professional\\VC\\Tools\\MSVC\\14.28.29333\\atlmfc\\lib\\x64" "-libpath:C:\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.18362.0\\ucrt\\x64" "-libpath:C:\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.18362.0\\um\\x64" -nologo "C:\\Users\\cnlohr\\AppData\\Local\\Temp\\rdtest-a9472b.o" gdi32.lib user32.lib openvr_api.dll "C:\\windows\\system32\\opengl32.dll" "C:\\windows\\system32\\msvcrt.dll"
lld-link: error: openvr_api.dll: bad file type. Did you specify a DLL instead of an import library?
lld-link: error: C:\windows\system32\opengl32.dll: bad file type. Did you specify a DLL instead of an import library?
lld-link: error: C:\windows\system32\msvcrt.dll: bad file type. Did you specify a DLL instead of an import library?
clang: error: linker command Failed with exit code 1 (use -v to see invocation)

^^ 失败

解决方法

您误读了 LLVM 的文档。我相信您所指的部分是:

链接到 DLL

完成。 LLD 可以读取链接 DLL 所需的导入库。支持按名称导出和按顺序导出。​​

它们与 MinGW / TinyCC 的“直接”(无 "%d.%d.%d.%d")链接的含义不同。它们的字面意思是“LLD 可以链接到 Windows 上的共享库,并且能够读取 .lib 文件来这样做”。这是真的,但您仍然需要 .lib,就像 MSVC 一样。

不幸的是,答案是在撰写本文时您不能让 Clang/LLD 这样做