loadlibrary 显式
时间: 2023-08-10 17:22:02 浏览: 123
loadlibrary 是一个 Windows API 函数,用于加载指定的 DLL 模块并返回该模块的句柄。它的原型如下:
```c++
HMODULE LoadLibrary(
LPCTSTR lpFileName
);
```
其中,lpFileName 参数是一个指向包含要加载的 DLL 文件名的字符串的指针。LoadLibrary 函数将返回一个 HMODULE 类型的句柄,该句柄用于引用已加载的 DLL 模块。
loadlibrary 函数在动态链接库中使用显式链接时非常有用。在显式链接中,函数的地址是在运行时动态解析的,而不是在编译时静态链接。这使得程序可以在运行时动态地加载和卸载 DLL,从而实现更加灵活的功能。
在使用 loadlibrary 函数加载 DLL 之后,可以使用 GetProcAddress 函数获取 DLL 中导出函数的地址,并调用导出函数。当不再需要使用该 DLL 时,可以使用 FreeLibrary 函数卸载该 DLL,释放该 DLL 占用的系统资源。
需要注意的是,使用 loadlibrary 函数加载 DLL 时,应该避免加载恶意或未经验证的 DLL,以避免安全漏洞。正确使用 loadlibrary 函数可以使程序实现更加灵活的功能,并提高程序的性能和可维护性。
相关问题
B.dll依赖于D.dll,C.dll依赖于D.dll。A.exe显式LoadLibrary加载了B.dll和C.dll,先FreeLibrary B.dll,再FreeLibraryC.dll,会发生什么?
当B.dll和C.dll之间存在依赖关系(即C.dll依赖于D.dll,而B.dll也依赖于D.dll),并且A.exe通过`ctypes.cdll.LoadLibrary`显式加载了B.dll和C.dll,按照通常的DLL动态链接顺序:
1. A.exe加载B.dll时,会自动查找并加载依赖的D.dll。
2. 接着,A.exe加载C.dll,同样会因为C.dll的依赖而加载D.dll。
如果在程序运行过程中,先调用`ctypes.cdll.FreeLibrary(B.dll)`释放B.dll,然后再尝试释放C.dll(`ctypes.cdll.FreeLibrary(C.dll)`),可能会遇到以下情况:
- 如果D.dll还没有被其他进程占用,那么释放B.dll可能不会立即影响到C.dll,因为它们共享同一份D.dll实例。
- 但如果D.dll正由C.dll或其他进程使用,试图释放B.dll可能导致C.dll访问已被卸载的D.dll资源,从而引发错误(如找不到库文件或内存访问异常)。
因此,建议在释放之前确保所有依赖的库都已经不再被使用,以避免潜在的程序崩溃或未定义的行为。如果程序设计允许,可以在适当的时候按正确的顺序释放这些库,或者使用更复杂的资源管理策略,比如使用Python的`atexit`模块来确保清理顺序。[^1]
loadlibrary函数实现
### LoadLibrary 函数实现细节
#### 动态链接库加载机制概述
Windows 操作系统提供了两种主要方法来加载动态链接库(DLL),即隐式加载和显式加载。`LoadLibrary` 是用于显式加载 DLL 的核心函数之一[^3]。
#### `LoadLibrary` 函数签名及其作用
`LoadLibrary` 接收一个指向包含要映射到调用进程地址空间的可执行模块名称字符串的指针作为输入参数,并返回该模块的一个句柄(HMODULE)。如果指定文件名不带路径,则会在多个预定义目录中查找此文件,直到找到为止。其原型如下:
```c++
HMODULE WINAPI LoadLibrary(
_In_ LPCTSTR lpFileName
);
```
- 参数说明:
- `lpFileName`: 要加载的DLL或其他.exe 文件的名字;可以是一个绝对路径或相对路径下的文件名。
- 返回值解释:
如果成功则返回已加载模块的句柄;否则返回NULL并设置GetLastError() 错误代码。
#### 加载过程解析
当调用了 `LoadLibrary` 后,系统会按照一定的顺序尝试定位目标DLL的位置,具体流程包括但不限于以下几个方面:
1. **检查缓存**: 首先查询当前进程中已经存在的模块列表,看是否存在相同名字的DLL已经被加载过;
2. **搜索路径** : 若未命中上述情况,则依据默认规则依次访问不同位置寻找所需的DLL文件,这些地方可能涉及应用程序所在的同一文件夹、系统的环境变量PATH所列明的地方以及注册表内记录的相关项等;
3. **内存映射** : 找到了正确的DLL之后,将其物理磁盘上的数据复制入虚拟内存区域形成镜像副本供后续操作使用;
4. **初始化处理** : 对于新引入的每一个DLL来说,在完成映射动作后还需要做必要的准备工作比如运行DllMain入口点处编写的启动逻辑等等。
#### 安全性和兼容性的考量
考虑到安全因素的影响,自 Windows Vista 开始微软推荐开发者们尽可能采用带有扩展属性版本号校验功能的新API——`LoadLibraryEx` 来代替传统的 `LoadLibrary` 方法以减少潜在风险。
阅读全文
相关推荐














