在主可执行文件的子文件夹中部署Qt C ++共享库的dll

时间:2016-08-23 23:20:08

标签: c++ dll deployment shared-libraries qt5

我有一个Qt5 C ++项目,包含一个主应用程序和一个(由我创建)共享库。它编译并执行,我能够部署它。问题是,通过部署,我需要将我的共享库的已编译dll放在与主可执行文件相同的目录中。但是,我希望保持顶级文件夹相对干净,并将必要的文件放在适当的文件夹子树中。所以,我的问题是,我应该在* .pro文件中放置什么才能将dll的路径更改为myApp / myLib,其中myApp是主应用程序可执行文件所在的文件夹。

2 个答案:

答案 0 :(得分:2)

Dynamic-Link Library Search Order相当静态。要包含子目录,需要自定义DLL加载。有很多方法可以实现您的目标。

  • 延迟加载库(请参阅Linker Support for Delay-Loaded DLLs)并在应用程序启动期间调整搜索路径 默认情况下,在任何代码运行之前,在进程初始化期间会加载编译时动态链接库。链接器提供延迟加载DLL的选项,直到程序调用该DLL中的函数。这为您提供了一个在应用程序启动期间调整DLL搜索路径 1 (例如调用SetDllDirectory)的机会窗口。
    注意:请记住,在运行任何用户代码之前初始化全局变量。如果全局的初始化程序引用延迟加载库中的符号,则在运行任何用户代码之前加载该库。对于这些情况,这不是解决方案。
  • 使用自定义延迟加载帮助程序延迟加载库(请参阅Understanding the Helper FunctionDeveloping Your Own Helper Function) 对于每次导入,系统都会调用辅助函数。除其他外,辅助函数负责加载模块。这允许实现任意复杂的库搜索。在这种特定情况下,最简单的方法是只为库加载设置通知挂钩(参见Calling Conventions, Parameters, and Return Type)。

还有其他方式,看起来很有吸引力,但你不应该真正使用它们。这是一个列表,包括不使用它们的理由:

  • 更改PATH环境变量:虽然易于实施,但这是解决本地问题的全局解决方案。更改全局环境变量会影响整个系统。它可以由用户和其他软件修改,从根本上破坏您的应用程序。它占用了宝贵的环境空间(What is the maximum length of an environment variable?)。
  • 更改当前目录:当前目录是动态链接库搜索顺序的一部分,因此更改它(例如通过.lnk的启动目录设置)可能会起作用。但是,当前目录在进程的所有线程之间共享,并且任何线程都可以随时更改它。从本质上讲,这使得当前目录无用(对于任何事情,真的)。

<小时/> 1 如果您提前知道库,则可以手动加载它们(LoadLibrary),并通过延迟加载辅助函数获取它们。但是,如果这些模块中的任何一个具有在标准搜索路径中找不到的依赖项,则会失败。

答案 1 :(得分:1)

由于Windows会为您的程序搜索DLL,而不是程序本身,因此您无法告诉makefile在哪里搜索库。

但是你可以:

  • 添加所需的文件夹,其中dll将转到PATH。
  • 制作启动脚本,设置库的路径,然后启动程序。
  • 根据您的情况,如果您遵守LPGL或Qt Comercial许可证,则静态编译。

作为旁注:Qt Plugins可以满足您的需求,但核心依赖项本身并不是Qt插件。