【问题标题】:How can an EXE have static dependency on a DLL?EXE 如何对 DLL 有静态依赖?
【发布时间】:2011-02-09 10:55:31
【问题描述】:

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

程序无法启动,因为 您的计算机缺少 XXX.dll。 尝试重新安装程序以修复 这个问题。

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

编辑:

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

【问题讨论】:

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


    【解决方案1】:

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

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

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

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

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

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

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

    【讨论】:

    • 您链接的 MSDN 页面使用术语“静态”...无论如何,简短的回答是通过添加 DLL 的关联 .lib,我导致 VS 隐式链接 DLL?但是如果我不添加那个 .lib 我会得到链接器错误,因为我调用了在 .h 文件中声明的方法。我可以告诉 VS not 隐式链接 DLL 但仍然以相同的方式工作吗?
    • @John 在列出隐式链接的其他常用术语时,它提到了术语static。在我看来,使用 static 来描述 dynamic 链接是误用。使用术语静态负载的问题在于它太容易与完全不同的静态链接混淆。
    • @John 您的问题与隐式与显式链接无关。问题是 DLL 不在搜索路径中。您需要将其放在搜索路径中。我不知道解决这个问题的最佳方法是什么。如果您告诉我们 DLL 的出处,那么我们可以建议您将它放在哪里。
    • 我不确定在加载 DLL 之前是否有设置搜索路径的方法,外部应用程序正在加载主 DLL 作为插件,这个想法是插件的资源(DLL,艺术品等)将在运行时确定的另一个文件夹中。这对于正常使用来说很好,但意味着在没有其他 DLL 存在的情况下,即使注册 DLL 也无法加载。
    • @John 现在这是一个不同的问题。我回答了你原来的问题。我建议您提出一个新问题并解释各种 exe 和 dll 文件如何组合在一起的所有细节。您还应该接受其他一些有很好答案的问题(当然从这个开始!!)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-30
    • 2010-10-22
    • 1970-01-01
    • 1970-01-01
    • 2011-05-20
    相关资源
    最近更新 更多