LoadLibraryW 函数 (libloaderapi.h)
将指定的模块加载到调用进程的地址空间中。 指定的模块可能会导致加载其他模块。
有关其他加载选项,请使用 LoadLibraryEx 函数。
语法
HMODULE LoadLibraryW(
[in] LPCWSTR lpLibFileName
);
参数
[in] lpLibFileName
模块的名称。 这可以是库模块(.dll 文件)或可执行模块(.exe 文件)。
如果指定的模块是可执行模块,则不会加载静态导入;而是使用 DONT_RESOLVE_DLL_REFERENCES
标志 LoadLibraryEx 加载模块。
指定的名称是模块的文件名,与库模块本身中存储的名称无关,由模块定义 (.def) 文件中的 LIBRARY 关键字指定。
如果字符串指定完整路径,则函数仅搜索模块的该路径。
如果字符串指定相对路径或没有路径的模块名称,则函数使用标准搜索策略查找模块;有关详细信息,请参阅“备注”。
如果函数找不到模块,该函数将失败。 指定路径时,请务必使用反斜杠(\),而不是正斜杠(/)。 有关路径的详细信息,请参阅 命名文件或目录。
如果字符串指定了没有路径的模块名称,并且省略文件扩展名,该函数会将默认库扩展名“.DLL”追加到模块名称。 若要防止函数将“.DLL”追加到模块名称,请在模块名称字符串中包含尾随点字符(.)。
返回值
如果函数成功,则返回值是模块的句柄。
如果函数失败,则返回值为 NULL。 若要获取扩展的错误信息,请调用 GetLastError。
言论
若要启用或禁用加载程序在 DLL 加载期间显示的错误消息,请使用 SetErrorMode 函数。
LoadLibrary 可用于将库模块加载到进程的地址空间中,并返回可在 GetProcAddress 中使用的句柄来获取 DLL 函数的地址。
LoadLibrary 还可用于加载其他可执行模块。 例如,该函数可以指定一个 .exe 文件来获取可在 findResource 或
如果指定的模块是尚未为调用进程加载的 DLL,则系统会使用 DLL_PROCESS_ATTACH 值调用 DLL 的 DllMain 函数。 如果 DllMain 返回 TRUE,LoadLibrary 返回模块的句柄。 如果 DllMain 返回 FALSE,则系统会从进程地址空间卸载 DLL,LoadLibrary 返回 NULL。 从 DllMain调用 LoadLibrary 是不安全的。 有关详细信息,请参阅 DllMain中的“备注”部分。
模块句柄不可全局或可继承。 对 LoadLibrary 的调用不会生成另一个进程可以使用的句柄,例如 ,在调用 GetProcAddress时。 另一个进程必须在调用 GetProcAddress之前为模块调用 LoadLibrary。
如果 lpFileName 不包含路径,并且有多个具有相同基名称和扩展的已加载模块,该函数将返回第一次加载的模块的句柄。
如果未在 lpFileName 参数中指定文件扩展名,则会追加默认库扩展名 .dll。 但是,文件名字符串可以包含尾随点字符 (.),以指示模块名称没有扩展名。 如果未指定路径,函数将搜索其基名称与要加载的模块的基名称匹配的已加载模块。 如果名称匹配,则负载会成功。 否则,该函数将搜索文件。
搜索的第一个目录是包含用于创建调用进程的映像文件的目录(有关详细信息,请参阅 CreateProcess 函数)。 这样做允许找到与进程关联的专用动态链接库 (DLL) 文件,而无需将进程的已安装目录添加到 PATH 环境变量。 如果指定了相对路径,则整个相对路径将追加到 DLL 搜索路径列表中的每个标记。 若要从相对路径加载模块而不搜索任何其他路径,请使用 GetFullPathName 获取非关系路径,并使用非关系路径调用 LoadLibrary。 有关 DLL 搜索顺序的详细信息,请参阅 Dynamic-Link 库搜索顺序。
可以使用 SetDllDirectory 函数更改搜索路径。 建议使用此解决方案,而不是使用 SetCurrentDirectory 或硬编码 DLL 的完整路径。
如果指定了路径,并且应用程序有重定向文件,该函数将在应用程序的目录中搜索模块。 如果模块存在于应用程序的目录中,LoadLibrary 会忽略指定的路径,并从应用程序的目录中加载模块。 如果应用程序目录中不存在模块,LoadLibrary 从指定目录中加载模块。 有关详细信息,请参阅 动态链接库重定向。
如果使用不带路径规范的程序集名称调用 LoadLibrary,并且程序集列在系统兼容清单中,则调用会自动重定向到并排程序集。
系统对所有已加载的模块维护按进程引用计数。 调用 LoadLibrary 递增引用计数。 调用 FreeLibrary 或 FreeLibraryAndExitThread 函数会减少引用计数。 当模块的引用计数达到零或进程终止时(无论引用计数如何),系统将卸载模块。
Windows Server 2003 和 Windows XP:Visual C++ 编译器支持一种语法,可用于声明线程局部变量:_declspec(thread)。 如果在 DLL 中使用此语法,则无法在 Windows Vista 之前的 Windows 版本中使用 LoadLibrary 显式加载 DLL。 如果 DLL 将显式加载,则必须使用线程本地存储函数,而不是 _declspec(thread)。 有关示例,请参阅 使用动态链接库中的线程本地存储。
安全备注
请勿使用 SearchPath 函数检索后续 LoadLibrary 调用的 DLL 路径。 SearchPath 函数使用与 LoadLibrary 不同的搜索顺序,并且它不使用安全进程搜索模式,除非通过调用 SetSearchPathMode 和 BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE显式启用此模式。 因此,SearchPath 可能首先搜索用户的当前工作目录以获取指定的 DLL。 如果攻击者已将 DLL 的恶意版本复制到当前工作目录中,SearchPath 检索的路径将指向恶意 DLL,LoadLibrary 将加载该 DLL。不要根据搜索 DLL 的 LoadLibrary 调用对操作系统版本做出假设。 如果应用程序在 DLL 合法不存在但 DLL 的恶意版本位于搜索路径中的环境中运行,则可能会加载 DLL 的恶意版本。 请改用 获取系统版本中所述的建议技术。
例子
有关示例,请参阅 使用 Run-Time 动态链接。
注意
libloaderapi.h 标头将 LoadLibrary 定义为一个别名,该别名根据 UNICODE 预处理器常量的定义自动选择此函数的 ANSI 或 Unicode 版本。 将中性编码别名与不中性编码的代码混合使用可能会导致编译或运行时错误不匹配。 有关详细信息,请参阅函数原型的
要求
要求 | 价值 |
---|---|
最低支持的客户端 | Windows XP [仅限桌面应用] |
支持的最低服务器 | Windows Server 2003 [仅限桌面应用] |
目标平台 | 窗户 |
标头 | libloaderapi.h (包括 Windows.h) |
库 | Kernel32.lib |
DLL | Kernel32.dll |