在程序启动时从另一个目录加载DLL

时间:2012-05-15 18:01:16

标签: c++ windows visual-studio dll

我的基本问题是:我的程序(MyProgram.exe)依赖于另一个程序的DLL(OtherProgram),我试图避免每次OtherProgram更新时重新打包一个新的DLL。我希望在启动时将OtherProgram的DLL中的MyProgram.exe链接,但我不完全确定Windows允许这样做。因此,如果有某种解决方法也可以接受。

只是在某些背景下,该平台是Windows 7 x64,当我在MyProgram.exe项目目录中创建一个符号链接到MyProgram的安装目录中的DLL时,MyProgram.exe正常运行。当我尝试在没有符号链接的情况下运行它时,我得到“程序无法启动,因为计算机中缺少OtherProgramDLL.dll”错误。

非常感谢任何有关相关信息的建议或链接!

编辑:澄清:DLL在编译时没有链接,这个问题在运行时出现

6 个答案:

答案 0 :(得分:12)

Windows世界中有两种类型的动态链接:

  1. Load-Time链接是指程序启动时自动加载DLL的时间。 Windows使用我将在下面讨论的特定算法找到此DLL。
  2. Run-Time链接是指通过在代码中调用LoadLibrary来专门加载DLL。类似的规则适用于如何找到库,但您可以指定一个完全限定或相对合格的路径来控制搜索。
  3. 对于加载时链接,MS建议您的程序的DLL存储在加载应用程序的同一目录中并从中加载。如果这完全可行,这可能是您的最佳选择。

    如果这不起作用,还有其他几个选项,outlined here。一种方法是通过将DLL放在工作目录或加载应用程序的目录中来利用搜索顺序。

    您可以通过以下方式更改应用程序的工作目录:

    1. 创建应用程序的快捷方式。
    2. 打开快捷方式的属性
    3. 使用DLL所在的目录编辑“Start in”属性。
    4. 使用快捷方式启动应用程序时,它将加载正确的DLL。

      加载时链接的其他选项包括:

      • 向您的应用程序添加清单,指明您的从属assemblies所在的位置,或
      • 设置PATH

答案 1 :(得分:2)

您可以将dll所在的目录添加到PATH环境变量中。

答案 2 :(得分:2)

您可以使用LoadLibrary,但您需要一种方法来保证DLL的位置。这个维基百科article提供了关于如何在加载DLL后使用它的好例子。

答案 3 :(得分:2)

I have struggled with the same problem and also found a dead end with the suggested methods like LoadLibrary, SetDllDirectory, Qt's addLibraryPath and others. Regardless of what I tried, the problem still remained that the application checked the libraries (and didn't find them) before actually running the code, so any code solution was bound to fail.

I almost got desperate, but then discovered an extremely easy approach which might also be helpful in cases like yours: Use a batch file! (or a similar loader before the actual application)

A Windows batch file for such a purpose could look like this:

@echo off
PATH=%PATH%;<PATH_TO_YOUR_LIB>
<PATH_TO_YOUR_APP_EXE>

/edit: Just saw @SirDarius comment in Luchian's answer which describes that way, so just take my batch code bit as a reference and all credits go to him.

答案 4 :(得分:0)

使用符号链接到第三方可执行文件

我发现Aaron Margosis倡导的方法很有用。参见:

  

Using NTFS Junctions to Fix Application Compatibility Issues on 64-bit Editions of Windows

实质上,创建指向每个从属第三方可执行文件的符号链接。将这些符号链接文件放在您自己的相关可执行文件中。除了对目标的文件名更改外,&#39; soft&#39;符号链接将解析加载时依赖性,即使未来更新更改了链接的目标。

答案 5 :(得分:0)

我正在处理的一个应用程序遇到同样的问题。

我不想使用运行时加载,因为手动创建函数指针需要数十个函数。

Dibling先生提到清单文件为我打开了一扇新门,但我遗憾地发现支持该功能的最旧版Windows是Windows 7.它甚至无法在Vista上运行。< / p>

长话短说,一位熟悉Windows应用程序开发的朋友告诉我查找Delay-Loaded DLL,结果是用最小的努力完美地解决问题。它会将DLL库的加载延迟到您手动执行的操作,或者第一次调用其函数时。所以你只需要在发生这种情况之前将你的DLL路径添加到搜索路径,SetDllDirectory帮助。

以下是使其有效的步骤:

1)通过makefile,cmake或VS属性页面指定要延迟加载到链接器的DLL(Linker-&gt; VS2015的输入)

2)在对DLL进行任何调用之前,在程序开头调用SetDllDirectory

延迟加载的DLL一直支持VC6。 XP SP1之后支持SetDllDirectory。