Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在程序启动时从另一个目录加载DLL_C++_Windows_Visual Studio_Dll - Fatal编程技术网

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

C++ 在程序启动时从另一个目录加载DLL,c++,windows,visual-studio,dll,C++,Windows,Visual Studio,Dll,我的基本问题是:我的程序(MyProgram.exe)依赖于另一个程序(OtherProgram)的DLL,我试图避免每次其他程序更新时重新打包新的DLL。我希望在其他程序启动时在其DLL中有MyProgram.exe链接,但我不完全确定Windows是否允许这样做。因此,如果有某种解决办法,这也是可以接受的 就一些背景而言,平台是Windows 7 x64,当我在MyProgram.exe项目目录中创建指向其他程序安装目录中DLL的符号链接时,MyProgram.exe运行良好。当我尝试在没有

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

就一些背景而言,平台是Windows 7 x64,当我在MyProgram.exe项目目录中创建指向其他程序安装目录中DLL的符号链接时,MyProgram.exe运行良好。当我尝试在没有符号链接的情况下运行它时,会出现“程序无法启动,因为您的计算机缺少OtherProgramDLL.dll”错误

非常感谢您的建议或相关信息的链接


编辑:澄清:DLL在编译时未链接,此问题在运行时出现

您可以将DLL所在的目录添加到
路径
环境变量中

可以使用,但需要一种方法来保证DLL的位置。本维基百科提供了加载DLL后如何使用DLL的良好示例。

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

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

    如果这不起作用,还有其他几种选择。一种是利用搜索顺序,将DLL放在工作目录或加载应用程序的目录中

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

  • 创建应用程序的快捷方式
  • 打开快捷方式的属性
  • 使用DLL所在的目录编辑“起始位置”属性
  • 当您使用快捷方式启动应用程序时,它将加载正确的DLL

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

    • 将清单添加到应用程序中,以指定您的受抚养人所在的位置,或
    • 设置
      路径

    我一直在努力解决同样的问题,也发现了一些建议方法的死胡同,如
    LoadLibrary
    setdldirectory
    、Qt的
    addLibraryPath
    等。不管我尝试了什么,问题仍然是应用程序在实际运行代码之前检查了库(但没有找到),因此任何代码解决方案都注定会失败

    我几乎绝望了,但后来发现了一种非常简单的方法,在像您这样的情况下也可能很有用:使用批处理文件(或实际应用之前的类似加载程序)

    用于此目的的Windows批处理文件可能如下所示:

    @echo off
    PATH=%PATH%;<PATH_TO_YOUR_LIB>
    <PATH_TO_YOUR_APP_EXE>
    
    @echo关闭
    路径=%PATH%;
    
    /编辑:刚刚看到了这样描述的注释,所以只需将我的批处理代码位作为参考,所有信用都归他所有。

    使用指向第三方可执行文件的符号链接 我发现他提倡的方法很有用。见:


    本质上,创建指向每个相关第三方可执行文件的符号链接。将这些符号链接文件放在您自己的相关可执行文件中。除了对目标文件名的更改外,“软”符号链接将解决加载时间依赖关系,即使链接的目标因将来的更新而更改。

    我正在使用的一个应用程序也存在同样的问题

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

    迪布林先生提到清单文件为我打开了一扇新的大门,但我遗憾地发现,最早支持该功能的windows版本是Windows7。它甚至不能在Vista上运行

    长话短说,一位熟悉Windows应用程序开发的朋友告诉我要查找,结果证明,它可以用最少的努力完美地解决问题。它会将DLL库的加载延迟到您手动执行的时间点,或第一次调用其函数的时间点。因此,在这之前,您只需要将DLL路径添加到搜索路径中,这会有所帮助

    以下是使其工作的步骤:

    1) 指定要延迟加载到链接器的DLL,可以通过makefile、cmake或VS属性页(链接器->VS2015的输入)

    2) 在程序开始时调用,然后再调用DLL

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

    工作正常!真不敢相信我没想到,哈哈。谢谢当你能做到这一点时,你正在用大锤敲开一个螺母。每当我遇到更改全局
    路径
    变量的程序时,我都会有一种不好的感觉。@David:同意。不要在小路上乱动。另一种选择是使用加载程序搜索dll的路径,并使用修改过的非全局路径环境变量运行“MyProgram.exe”。错误。如果exe链接到库,无论您在哪里调用LoadLibrary,都为时已晚。我没有进行下载投票,但您通常不希望
    LoadLibrary
    DLL。当然不仅仅是为了你可以指定它所在的路径。@LuchianGrigore:公平地说,它可以从库中取消链接。@JohnDibling我不同意你的第一个评论。存在var