我正在使用 native C++ 编写 Windows 应用程序插件(作为 DLL)。我们称它为 myplugin.dll
。我的插件引用了另一个 DLL,我们称之为 other.dll
。
我的插件安装在应用程序的 plugins
目录的 myplugin
子目录中:
application.exe
plugins\
myplugin\
myplugin.dll
myplugin.dll
隐式链接到 other.dll
。我无法延迟加载 other.dll
,因为它公开了具有虚拟方法的类,并且虚拟方法表被视为数据,无法从延迟加载的 DLL 中导入它们。
我很自然地希望将 other.dll
放在 plugins\myplugin
目录中,在 myplugin.dll
旁边,但默认情况下是 Windows搜索 other.dll
( source ) 时不会在 plugins\myplugin
中查找。
除了将 other.dll
放在应用程序的根目录之外,我还有什么选择?
(虽然问题 Altering DLL search path for static linked DLL 是相关的,但它描述了一个不太有意义的场景:一个应用程序隐式链接到一个插件 DLL。我相信一个清晰的典型场景可能有助于发现额外的解决方案这个常见问题,例如当应用程序加载 myplugin.dll
时显式加载 other.dll
,如果可能的话。)
编辑:另一个类似的问题:Plugin DLLs that depend on other DLLs
编辑:我找到了问题的解决方案,请参阅下面接受的答案。据我所知,这是最干净的解决方案。我希望它对其他人有帮助。
最佳答案
我在对我的问题的最后评论中概述的想法被证明是一个很好的想法。
我将 myplugin.dll
更改为一个简单的 shim动态链接库。该垫片的入口点执行以下操作:
- 它首先从包含 shim 的目录加载
other.dll
(使用LoadLibrary
),在我的例子中是plugins\myplugin\
。 - 然后从同一目录加载“真正的”插件
myplugin-impl.dll
。
myplugin.dll
然后简单地将所有调用转发给执行实际工作的 myplugin-impl.dll
。
请注意,myplugin-impl.dll
仍然隐式链接到 other.dll
。但是,当 myplugin-impl.dll
被加载时,other.dll
已经被应用进程地址空间中的 shim 加载,所以不会再加载。
通过此解决方案,我们可以获得隐式 DLL 加载(特别是使用虚拟方法加载 C++ 类)的好处,同时仍然可以完全控制隐式加载 DLL 的加载位置和加载方式。
关于c++ - 插件 DLL 引用的 DLL 的搜索路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36814862/