插件DLL引用的DLL的搜索路径 [英] Search path for a DLL referenced by a plug-in DLL
问题描述
我正在用本机C ++编写Windows应用程序插件(作为DLL).我们称之为myplugin.dll
.我的插件引用了另一个DLL,我们将其称为other.dll
.
I'm writing a Windows application plug-in (as a DLL) in native C++. Let's call it myplugin.dll
. My plug-in references another DLL which we'll call other.dll
.
我的插件安装在应用程序plugins
目录的myplugin
子目录中:
My plug-in is installed in the myplugin
subdirectory of the application's plugins
directory:
application.exe
plugins\
myplugin\
myplugin.dll
myplugin.dll
隐式链接到other.dll
.我无法延迟加载other.dll
,因为它公开了带有虚拟方法的类,并且虚拟方法表被视为数据,因此无法从延迟加载的DLL中导入它们.
myplugin.dll
links implicitly to other.dll
. I cannot delay-load other.dll
because it exposes classes with virtual methods, and virtual method tables being considered as data, they cannot be imported from delay-loaded DLLs.
我自然希望将other.dll
放在myplugin.dll
旁边的plugins\myplugin
目录中,但是默认情况下,Windows在搜索other.dll
时不会在plugins\myplugin
中查找(
I would naturally like to place other.dll
in the plugins\myplugin
directory, next to myplugin.dll
, but by default Windows will not look in plugins\myplugin
when searching for other.dll
(source).
除了在应用程序的根目录中放置other.dll
之外,我还有什么选择?
What are my options here, other than placing other.dll
in the root directory of the application?
(而问题为静态链接DLL更改DLL搜索路径是相关的,它描述的场景不太有意义:应用程序隐式链接到插件DLL,我认为一个清晰,典型的场景可能有助于发现该常见问题的其他解决方案,例如显式如果可能,则在应用程序加载myplugin.dll
时加载other.dll
.)
(While the question Altering DLL search path for static linked DLL is related, it describes a scenario that doesn't quite make sense: an application implicitly linking against a plug-in DLL. I believe that a clear, typical scenario may help uncover additional solutions to this common issue, such as explicitly loading other.dll
when myplugin.dll
gets loaded by the application, if that would be possible.)
另一个类似的问题:依赖于其他DLL的插件DLL
我找到了解决问题的方法,请参见下面的可接受答案.据我所知,这是最干净的解决方案.我希望它可以帮助其他人.
I found a solution to the problem, see the accepted answer below. As far as I know, this is the cleanest solution. I hope it helps someone else.
推荐答案
我在对问题的最后评论中概述的想法被证明是一个很好的想法.
The idea I outlined in the last comment to my question turned out to be a good one.
我将myplugin.dll
更改为简单的 shim DLL.该垫片的入口点执行以下操作:
I changed myplugin.dll
to be a simple shim DLL. The entry point of that shim performs the following operations:
- It first loads
other.dll
(usingLoadLibrary
) from the directory containing the shim,plugins\myplugin\
in my case. - It then loads
myplugin-impl.dll
, the "real" plug-in, from the same directory.
myplugin.dll
然后将所有呼叫简单转发到myplugin-impl.dll
即可完成实际工作.
myplugin.dll
then simply forward all calls to myplugin-impl.dll
which does the actual job.
请注意,myplugin-impl.dll
仍隐式链接到other.dll
.但是,在加载myplugin-impl.dll
时,填充程序已经在应用程序进程的地址空间中加载了other.dll
,因此不会再进行加载.
Note that myplugin-impl.dll
still links implicitly to other.dll
. However, when myplugin-impl.dll
is loaded, other.dll
has already been loaded by the shim in the address space of the application's process so no further loading occurs.
通过这种解决方案,我们可以获得隐式DLL加载的好处(特别是使用虚拟方法加载C ++类),同时仍然可以完全控制隐式加载的DLL的加载位置和加载方式.
With this solution, we get the benefits of implicit DLL loading (in particular loading C++ classes with virtual methods) while still having full control on where the implicitly-loaded DLL is loaded from and how it is loaded.
这篇关于插件DLL引用的DLL的搜索路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!