我的目录结构如下:
test
dir
a.dll <-- version 1
a.dll <-- version 2
myapp.exe
我希望自己LoadLibrary("dir\\a.dll")
将使用版本1而LoadLibrary("a.dll")
将使用版本2,而在一起:
LoadLibrary("dir\\a.dll");
LoadLibrary("a.dll");
根据the documentation of LoadLibrary
,两者都将引用版本1。
但是,当我尝试在我正在处理的应用程序中执行此操作时,第1行加载版本1,第2行加载版本2.
我试过写一个小的重现器但是在重现器中它按预期工作 - 所以有一些东西在较大的应用程序或加载的dll中打破了。 导致这种情况的原因,以及如何解决?
要强调的是,两个负载在较大的应用程序中是相邻的,在第1行和第2行之间没有系统调用(当然它是相同的过程)。我原本确实想在它们之间放置很多代码,但是看到这个问题并在它们相邻时再现它。
我也试过以下目录结构:
test
dir
a.dll <-- version 1
myapp.exe
Windows
System32
a.dll <-- version 2
但是,第1行加载版本1,第2行加载版本2.
答案 0 :(得分:1)
我设法找到了解决方案。实际上,它只需要一些思考 - 回想起来答案是显而易见的:当我的第一个LoadLibrary
调用之前已经加载了dll时,就会出现这种情况。所以第一次调用,使用显式路径,加载版本1 - 而第二次调用,没有路径,默认为第一个加载的dll(根据文档),恰好是版本2。
可以通过在第一次LoadLibrary
调用之前强行卸载库来解决此问题:
HMODULE alreadyLoaded = GetModuleHandle("a.dll");
if (alreadyLoaded) {
FreeLibrary(alreadyLoaded);
}
虽然这对我来说已经足够了,但是更完整的解决方案是循环执行,以处理dll之前多次加载的情况:
HMODULE alreadyLoaded = GetModuleHandle("a.dll");
while (alreadyLoaded) {
FreeLibrary(alreadyLoaded);
alreadyLoaded = GetModuleHandle("a.dll");
}
当然,这有潜在危险 - 特别是如果原始HMODULE
存储在某处,因为这会使其无效。