windows - EXE 如何对 DLL 具有静态依赖性?

标签 windows visual-studio visual-c++ dll

通常在尝试运行使用 DLL 的 EXE 时,如果缺少 DLL,您会收到标准的 Windows 错误:

The program can't start because XXX.dll is missing from your computer. Try reinstalling the program to fix this problem.

这似乎是在您的任何代码被调用之前内置到 EXE 中的……它是如何工作的,以及在 Visual Studio 中构建项目时如何设置它?

编辑:

在我的特定场景中,我实际上有一个 DLL,它对其他 DLL 具有“静态”依赖性,因此如果这些 DLL 不存在,则注册我的 DLL 会失败,这有点难以诊断。但我宁愿不手动列出使用过的 DLL 函数,因为有很多!

最佳答案

当您链接到一个 DLL 时,有两种方法可以做到这一点,隐式链接和显式链接。您遇到的是隐式链接失败。

隐式链接通过包含在使用 PE(可移植可执行文件)格式的可执行镜像中称为导入表的东西进行操作。 PE 格式定义了导入表和导出表。导出表包含 DLL 导出的函数列表及其入口点。导入表包含对其他模块的隐式依赖。

当可执行文件启动时,加载器读取导入表,然后尝试加载所有引用的 DLL 以及这些 DLL 中的所有函数。如果未找到 DLL、DLL 无法正确加载或 DLL 不包含引用的函数,这可能会失败。在您的情况下,它失败了,因为加载程序在 DLL 搜索路径中没有找到 XXX.dll

链接器将生成导入表。在 C++ 中,这通常是通过该 DLL 的 .lib 文件完成的。

显式链接是您的代码调用 LoadLibraryGetProcAddress 以加载 DLL 及其函数的地方。当您想要编写可以在不同系统上运行的应用程序时,通常会使用这种方法。例如,您可能希望使用仅在特定版本的操作系统上存在的某些功能,但在旧版本的操作系统上运行时会降级为某些其他行为。

在提到链接到 DLL 时,不应使用术语static。静态链接是指函数的实现包含在图像中而不是包含在外部库中。

MSDN article该主题解释了所有这些以及更多内容。

关于windows - EXE 如何对 DLL 具有静态依赖性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4943889/

相关文章:

c++ - 对于具有相同调用堆栈的同一对象,从同一线程调用两次函数

无法使用 Visual C++ 编译器包含某些头文件

c++ - 在结构中创建结构

c++ - malloc 未分配指定内存(64 位)

wpf - 更换桌面墙纸/在桌面上绘制

windows - 如何使用 REST+cURL 更新 TeamCity 构建参数

c - 我怎样才能在 C 中获得一个进程句柄而不是它的名字?

c# - 为什么 MS 在新的 Windows 应用商店应用模板中去掉了 BindableBase?

c++ - 如何在 C++ 中获取 DLL 文件的版本信息

c# - 使用动态 Linq 过滤集合