我的目录结构如下:
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。
最佳答案
我设法找到了解决方案。事实上,它只需要一些思考——回想起来答案是显而易见的:当我第一次调用 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
存储在某个地方,因为这会使其无效。
关于c - LoadLibrary 不重用已加载的库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21812999/