c - LoadLibrary 不重用已加载的库

标签 c windows dll loadlibrary

我的目录结构如下:

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/

相关文章:

您可以使用 scanf 从单个位置读取 int 或 char 吗?

windows - 如何在 Windows Azure 中安装和使用 COM 对象?

c - 加密c源文件

c - Windows 下 feof() 的奇怪行为

c# - 添加 dll 引用到 asp.net mvc 应用程序,无需重新启动应用程序

dll - F#:Microsoft.FSharp.Data.TypeProviders 是否需要配置文件 47?

c - 如何在C中获得左移值?

c++ - `-g -rdynamic` gcc 标志是否显着减慢应用程序执行(增加性能消耗)?

c - 如何在算术运算中使用文件中的结构变量?

c++ - TCP Sockets什么时候需要Keep-alive?