gpt4 book ai didi

C++: list 和从不同目录动态加载 DLL

转载 作者:可可西里 更新时间:2023-11-01 17:59:40 28 4
gpt4 key购买 nike

关于我想要实现的目标的长篇故事

我正在开发一个将 DLL 作为插件动态加载的程序。我正在使用 Microsoft Visual C++ 2008 编译程序。不过,我们假设应该支持 Qt 工作的任何 Visual C++ 版本。程序目录布局如下:

| plugins/
| plugin1.dll
| plugin2.dll
| QtCore4.dll
| QtGui4.dll
| program.exe

program.exe 发现所有插件 DLL 文件,对它们执行 LoadLibrary() 并调用某个签名函数以查明它是否真的是一个插件。这在安装了适用于 MSVC90 的 vcredist 的计算机上运行良好。当然,为了使程序在所有计算机上运行,​​我必须使用 msvc*.dll 文件和适当的 list 文件重新分发它。 Qt DLL 也需要 redist 才能运行。

现在,我已将 cmake 设置为根据所选的 Visual Studio 版本自动复制适当的 redist DLL 和 list 。为了简单起见,让我们继续假设我正在使用 MSVC90。当 redist 被复制到程序目录时,布局如下所示:

| plugins/
| plugin1.dll
| plugin2.dll
| QtCore4.dll
| QtGui4.dll
| msvcm90.dll
| msvcp90.dll
| msvcr90.dll
| Microsoft.VC90.CRT.manifest (I'm also aware that this file is bugged in VS2008)
| program.exe

关于 list 文件中的错误:http://www.cmake.org/pipermail/cmake/2008-September/023822.html

问题

具有此布局的程序现在可以在未安装 redist 的计算机上运行,​​插件未加载。为了加载插件,我必须执行以下操作之一:

  1. 将 list 文件复制到 plugins/ 目录。从 list 文件中删除对 msvc*.dll 文件的所有引用。这行得通,但并不好,因为我必须根据使用的 MSVC 版本支持不同版本的已编辑 list 文件。另外,我不知道这是否会破坏除 2008 以外的 Visual Studio。
  2. 将整个 redist 复制到 plugins/ 目录。这不需要对 list 文件进行任何修改,但现在 program.exe 愚蠢地尝试加载 msvc*.dll 文件,认为它们是插件。自然地,这会优雅地失败,所以不会造成太大的伤害。另一个缺点是程序包的大小增加了 1 MB 以上。不过,我可以忍受这两个问题。
  3. 使用/MT 开关编译插件。简短测试表明这确实有效,但我不确定如果 Qt 和 program.exe 都是/MD,它将来是否不会破坏任何东西。

问题

什么是最好的解决方案?什么是正确的解决方案?如果有不止一种正确的解决方案,那么哪种是最佳做法?我是第一个尝试这样做的人吗?

更新 1(2012 年 11 月 18 日)

虽然问题仍未得到解答,但我决定选择引起最少头痛的途径。到目前为止,我一直在使用 1 号解决方案,我决定坚持使用它。如果 CMake 检测到用户使用的 MSVC 版本不同于 2008,它将显示一条警告消息,指出不完全支持自动打包。

最佳答案

如果您的目标操作系统有 _WIN32_WINNT >= 0x0502 则您可以使用函数

SetDllDirectory()

在加载插件之前。

放置主程序文件夹的路径。

调用覆盖系统加载顺序:

  1. 应用程序加载的目录。
  2. SetDllDirectory() 调用中的路径指定的目录。

因此,您可以在应用程序启动后调用该函数。在所有情况下都是安全的。祝你好运!

关于C++: list 和从不同目录动态加载 DLL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13223383/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com