admin 管理员组

文章数量: 1184232

在我们平时开发过程中,会遇到多次调用加载同一个DLL的场景,这样会不会多次加载,有冗余呢?

在 Windows 中, LoadLibrary 函数用于加载动态链接库(DLL)。经过代码测试,答案是 否定的 LoadLibrary 不会重复加载同一个 DLL 多次,而是会返回已经加载的 DLL 的句柄。

代码的测试过程以及相关原理

  1. 单次加载

    • 当你第一次调用 LoadLibrary 加载某个 DLL 时,操作系统会加载该 DLL 并将其映射到调用进程的地址空间中。
    • 如果你再次调用 LoadLibrary 加载同一个 DLL,操作系统不会重新加载该 DLL,而是会返回之前加载的 DLL 的句柄。
  2. 引用计数

    • Windows 内部维护一个引用计数,用于跟踪每个加载的 DLL 被引用的次数。
    • 每次调用 LoadLibrary 加载同一个 DLL 时,引用计数会增加。
    • 当调用 FreeLibrary 释放 DLL 时,引用计数会减少。当引用计数降为零时,DLL 才会从内存中卸载。
  3. DEMO代码(仅参考)

    #include<windows.h>#include<stdio.h>intmain(){// 第一次加载 DLL
        HMODULE hModule1 =LoadLibrary("mylib.dll");if(hModule1 ==NULL){printf("Failed to load mylib.dll\n");return1;}// 第二次加载同一个 DLL
        HMODULE hModule2 =LoadLibrary("mylib.dll");if(hModule2 ==NULL){printf("Failed to load mylib.dll\n");return1;}// 检查两个句柄是否相同if(hModule1 == hModule2){printf("Both handles point to the same DLL instance.\n");}else{printf("Handles point to different DLL instances.\n");}// 释放 DLLFreeLibrary(hModule1);FreeLibrary(hModule2);return0;}

    运行结果:

    Both handles point to the same DLL instance.
    

    这个示例展示了两次调用 LoadLibrary 加载同一个 DLL 时,返回的句柄是相同的。

需要注意的是

  1. 线程安全

    • LoadLibrary 是线程安全的,多个线程可以同时调用 LoadLibrary 加载同一个 DLL,而不会导致问题。
  2. 依赖关系

    • 如果 DLL 依赖于其他 DLL,操作系统会自动加载这些依赖的 DLL。
  3. 错误处理

    • 如果 LoadLibrary 失败(例如,DLL 不存在或依赖的 DLL 加载失败),应使用 GetLastError 获取错误码,并进行适当的错误处理。
  4. 版本管理

    • 如果需要加载不同版本的同一个 DLL,可以使用不同的路径或文件名。例如,我们可以使用完整路径或不同的文件名来加载不同版本的 DLL。

本文标签: 加载同一 编程 次调用