Visual C++:插件 DLL 使用的第 3 方 DLL 的位置?

Posted

技术标签:

【中文标题】Visual C++:插件 DLL 使用的第 3 方 DLL 的位置?【英文标题】:Visual C++: Location of 3rd-party DLL used by plugin DLL? 【发布时间】:2013-02-09 02:03:38 【问题描述】:

我正在为第 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 中有一些配置选项?

【问题讨论】:

@thang:触摸。我该怎么做? 啊,好问题,应该把它放到帖子里:p 【参考方案1】:

问题在于 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 的位置。此方法的另一个优点是,如果您找不到插件所需的库,您可能仍会激活插件,但功能会减少,或者至少提供有意义的错误/日志消息。

【讨论】:

【参考方案2】:

您想要做的是将 DLL 加载延迟到稍后使用这样的东西:

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

Delay Loading DLLs

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

Prevent .lib from loading DLL at runtime

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

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

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

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

当延迟加载发生时,它会在该目录中查找 dll 和 viola...

【讨论】:

【参考方案3】:

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

【讨论】:

以上是关于Visual C++:插件 DLL 使用的第 3 方 DLL 的位置?的主要内容,如果未能解决你的问题,请参考以下文章

调试由 C# Visual Studio 2010 插件导入的 C++ dll

在 Visual Studio 6 中从 VB 调用 VS2010 C++ dll

使用 Visual Studio 2015、C++ 项目的 DLL 没有“复制到输出目录”

本机 C++ 通过代理 C++ 托管 dll 使用 C# dll

.NET 异常处理程序导致 Visual C++ 6.0 异常的堆栈溢出

在 Visual Studio C++ 中使用 DLL