在Windows系统中部署Qt DLL

5

我有一个来自另一家公司的应用程序插件。我的插件使用Qt,因此需要Qt DLL。我的问题是所有4.x版本的Qt DLL都被称为相同的名称,例如:QtCore4.dll。很可能其他插件或将自己插入PATH环境变量的另一个应用程序已经将Qt dll放在了应用程序文件夹中。在这种情况下,插件将无法启动,因为它期望不同版本的DLL。

  • Q1. DLL部署的建议常规做法是什么?
  • Q2. 如果主机应用程序使用不同版本的Qt会怎样?Windows是否允许主机应用程序和插件使用不同的版本?

谢谢!

6个回答

3

为了帮助其他人解决这个问题:

QT DLL的版本在所有4.X版本中保证是相同的(或者至少是二进制兼容的)。这也是Qt dll命名中没有第二个数字的原因,因此不会出现问题。


3
然而,如果两个不同的Qt构建的配置不同,它们就不能进行二进制兼容。 - swongu
那么QT DLL的32位和64位版本呢? 它们也不是二进制兼容的。 - Patrick

3

A1: 最佳实践:将DLL文件放在可执行文件目录中。这样加载DLL文件时,程序会首先在该目录下查找。这是一种常见做法。

A2: 如果某个应用程序使用了与你所描述的模块需要的Qt版本不同的版本,则可能会导致问题(无法工作、崩溃等)。

使用静态链接时,还必须考虑到Qt许可限制。只要库在运行时动态加载并可与应用程序分离,LGPL许可证就不会有问题。但这仅适用于您不发布源代码等情况。

此外,您的安装程序应设置对这些文件的访问权限,以免受到其他恶意应用程序的覆盖。


1

从Windows XP开始的版本(即XP、2003、Vista、2008和Win7),您可以使用并置程序集DLL重定向。在任何情况下,您实际上所做的是包含一个小型文本文件,告诉操作系统您需要使用与可执行文件位于同一目录中的DLLs的特定版本。

这些是不太为人知的功能,但它们确实可以使您免受“DLL地狱”的困扰。


并排缓存使得在大型网络中部署应用程序变得更加困难。我更喜欢简单的、零安装、xcopy-install应用程序,你只需要复制exe和一些DLL文件,或者你甚至不必复制它,只需将其放在网络驱动器上。使用并排缓存DLL,您被迫在每台PC上显式安装应用程序。如果下一个版本需要新的DLL,那么您还必须重新安装该应用程序。 - Patrick

0

为了安全起见,您必须确保应用程序使用您想要使用的dll版本。Windows保证首先查找应用程序文件夹。因此,您应该将所有二进制依赖项放在那里。

如果您的应用程序在资源管理器中双击时无法运行,Windows会告诉您它需要哪个dll。将该dll复制到应用程序文件夹中。如果您的应用程序运行,则进行下一步。

现在,您应该逐个临时删除(或重命名)已放置在应用程序文件夹中的dll,并每次双击应用程序。如果Windows没有抱怨它在其他地方找到了dll,请将该dll从PATH环境中移除(可能是临时的)。Rapid Environment Editor是一个免费实用程序,可编辑立即生效的环境变量。

只有当您确定应用程序使用应用程序目录中的dll并且不从其他地方拉取任何dll时,才可以开始编辑PATH变量以恢复旧情况。


0

有没有办法选择使用静态链接 Qt?

我会将 DLL 文件部署在与我的应用程序/插件相同的目录中。

这并不能回答你的其他问题。


据我所知,静态链接只允许商业Qt许可证。 LGPL许可证要求您允许客户使用新版本的Qt“重新链接”您的应用程序,实际上意味着: 要么公开您的应用程序的源代码或目标文件。 要么分发Qt作为DLL文件。 - Patrick

0

像Tim说的那样,你应该将DLL部署到与你正在制作的应用程序/插件相同的目录中。我认为PATH变量不是你的程序将查找QT4 dll的第一个地方,因此如果你将其部署在同一个文件夹中,你的应用程序将选择与你的应用程序配套的那个dll并忽略路径中的任何dll。

问1:过去似乎每个人都会将他们的DLLs投放到系统32文件夹中,因为他们知道它在PATH中并且知道他们的程序能够找到它。从用户的角度来看,当我想卸载某些东西时,我发现这非常难清理。现在存储器的价格很低,我建议你保持你的DLL和你的应用程序在一起,特别是如果它们像这样可能有多个版本的话。虽然我不是专家,但这就是我处理Java应用程序的jar文件的方式。

问2:我想是的。这取决于应用程序和插件的目录结构。你可以告诉你的插件使用哪个版本,我愿意打赌应用程序已经将其版本放在一个特殊的地方了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接