1

我正在为第 3 方 Windows 应用程序编写 C++ 插件 DLL。我的插件 DLL 可以存在于文件系统上的任何位置,我在从 3rd-party 应用程序加载它时指定它的位置。

我的 DLL 的部分功能需要我使用第 3 方库 ( ZeroMQ )。我将我的 DLL 链接到 ZeroMQ 库并正确构建。但是,在第 3 方应用程序中加载我的 DLL 时,我一直收到The specified module could not be found.错误消息。最初,我不清楚我是否也需要 zeromq DLL 是否使用 ZeroMQ 静态库(但显然通常有一个静态库来包装对 DLL 的访问:Using .dll in Visual Studio 2010 C++)。

我尝试将零 mq dll(在我的情况下为 libzmq-v100-mt-gd-3_2_2.dll)与我的插件 DLL 放在同一个文件夹中,但这不起作用。

最后通过纯粹的实验,我发现我可以将 zeromq dll 直接放在与第 3 方主应用程序相同的文件夹中,现在我的插件可以工作了。但是,理想情况下,我宁愿不这样做。有没有办法让我以某种方式将 zeromq dll 库与我的插件 DLL 放在同一个文件夹中?如果是这样,怎么办?在构建我的 DLL 时,也许 Visual Studio 中有一些配置选项?

4

3 回答 3

2

问题是 Windows 在定位 dll 时使用的搜索路径包括应用程序的路径,而不是您的插件 dll 的路径(除非您可以说服应用程序供应商添加此功能!)。加载插件 dll 时,加载器发现它需要从 libzmq-v100-mt-gd-3_2_2.dll 导出的函数,并试图找到它。您所发现的与预期的一样 - 应用程序目录位于 dll 搜索路径中,因此如果您将 libzmq-v100-mt-gd-3_2_2.dll 放在那里,加载器将正确找到它,并继续加载您的插件 dll。有一些方法可以将插件的路径添加到搜索路径,但不幸的是,这些方法不能在您的 dll 中使用,因为您的代码只有在 dll 正确加载的情况下才会运行 - 如果 libzmq-v100- 则不会未找到 mt-gd-3_2_2.dll!

正如建议的那样,延迟加载可以解决问题。我可以看到的其他选项是:

  • 在您的插件安装程序中将您的插件的路径添加到 PATH 环境变量中,并将 libzmq-v100-mt-gd-3_2_2.dll 放在同一位置 - 这种方法会污染 PATH 变量,并且可能很脆弱
  • 使用动态链接而不是静态链接到您的插件所需的 libzmq-v100-mt-gd-3_2_2.dll - 然后您可以直接控制使用 LoadLibrary 加载 dll 的位置。这种方法的另一个优点是,如果您找不到插件所需的库,您可能仍然会激活插件,但功能会减少,或者至少提供有意义的错误/日志消息。
于 2013-02-09T07:56:16.447 回答
2

您想要做的是将 DLL 加载延迟到稍后使用以下内容:

http://msdn.microsoft.com/en-us/library/151kt790.aspx

延迟加载 DLL

http://www.codeproject.com/Articles/9428/Delay-Loading-a-DLL

防止 .lib 在运行时加载 DLL

然后在加载发生之前,使用 LoadLibrary 动态加载 DLL,您可以在其中输入 dll 的整个路径。

当延迟加载发生时,它会意识到 DLL 已经被您的 LoadLibrary 调用加载了,并且 viola...

或者,您也可以使用以下命令将目录添加到 dll 搜索路径,而不是使用 LoadLibrary 加载:

http://msdn.microsoft.com/en-us/library/ms686203.aspx

当延迟加载发生时,它将在该目录中查找 dll,然后中提琴...

于 2013-02-09T07:26:40.927 回答
0

我最近在一篇博文中解决了这个确切的问题:http: //otb.manusoft.com/2013/01/using-delayload-to-specify-dependent-dll-path.htm

于 2013-02-12T04:58:07.840 回答