LoadLibraryW 函数 (libloaderapi.h)

将指定的模块加载到调用进程的地址空间中。 指定的模块可能会导致加载其他模块。

有关其他加载选项,请使用 LoadLibraryEx 函数。

语法

HMODULE LoadLibraryW(
  [in] LPCWSTR lpLibFileName
);

参数

[in] lpLibFileName

模块的名称。 这可以是库模块 (.dll 文件) ,也可以是可执行模块 (.exe 文件) 。 如果指定的模块是可执行模块,则不会加载静态导入;相反,模块就像使用 标志的 LoadLibraryExDONT_RESOLVE_DLL_REFERENCES 加载一样。

指定的名称是模块的文件名,与库模块本身中存储的名称无关,该名称由 module-definition (.def) 文件中的 LIBRARY 关键字 (keyword) 指定。

如果字符串指定完整路径,则函数仅搜索模块的该路径。

如果字符串指定相对路径或模块名称而不指定路径,则函数使用标准搜索策略来查找模块;有关详细信息,请参阅备注。

如果函数找不到模块,该函数将失败。 指定路径时,请务必使用反斜杠 (\) ,而不是使用 /) (正斜杠。 有关路径的详细信息,请参阅 命名文件或目录

如果字符串指定模块名称而不指定路径,并且省略文件扩展名,则该函数会将默认库扩展“.DLL”追加到模块名称。 若要防止函数将“.DLL”追加到模块名称中,请在模块名称字符串中包含尾随点字符 (.) 。

返回值

如果函数成功,则返回值是模块的句柄。

如果函数失败,则返回值为 NULL。 要获得更多的错误信息,请调用 GetLastError。

注解

若要启用或禁用加载程序在 DLL 加载期间显示的错误消息,请使用 SetErrorMode 函数。

LoadLibrary 可用于将库模块加载到进程的地址空间中,并返回可在 GetProcAddress 中用于获取 DLL 函数地址的句柄。 LoadLibrary 还可用于加载其他可执行模块。 例如, 函数可以指定 .exe 文件以获取可在 FindResourceLoadResource 中使用的句柄。 但是,请勿使用 LoadLibrary 运行 .exe 文件。 请改用 CreateProcess 函数。

如果指定的模块是尚未为调用进程加载的 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 搜索顺序的详细信息,请参阅 动态链接库搜索顺序

可以使用 SetDllDirectory 函数更改搜索路径。 建议使用此解决方案,而不是使用 SetCurrentDirectory 或硬编码 DLL 的完整路径。

如果指定了路径,并且应用程序有重定向文件,则函数会在应用程序的 目录中搜索模块。 如果模块存在于应用程序的目录中, LoadLibrary 将忽略指定的路径,并从应用程序的目录中加载模块。 如果模块不存在于应用程序的目录中, LoadLibrary 将从指定的目录中加载该模块。 有关详细信息,请参阅 动态链接库重定向

如果使用没有路径规范的程序集的名称调用 LoadLibrary ,并且程序集列在系统兼容清单中,则调用会自动重定向到并行程序集。

系统在所有加载的模块上维护每个进程的引用计数。 调用 LoadLibrary 会递增引用计数。 调用 FreeLibraryFreeLibraryAndExitThread 函数会减少引用计数。 当模块的引用计数达到零或进程终止 (时,无论引用计数) 如何,系统都会卸载模块。

Windows Server 2003 和 Windows XP: Visual C++ 编译器支持用于声明线程局部变量的语法: _declspec (线程) 。 如果在 DLL 中使用此语法,将无法在 Windows Vista 之前的 Windows 版本中使用 LoadLibrary 显式加载 DLL。 如果 DLL 将被显式加载,则必须使用线程本地存储函数,而不是 _declspec (线程) 。 有关示例,请参阅 在动态链接库中使用线程本地存储

安全备注

请勿使用 SearchPath 函数检索 DLL 的路径,以便进行后续 的 LoadLibrary 调用。 SearchPath 函数使用的搜索顺序与 LoadLibrary 不同,并且它不使用安全进程搜索模式,除非通过调用具有 BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODESetSearchPathMode 显式启用此模式。 因此, 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 [仅限桌面应用]
目标平台 Windows
标头 libloaderapi.h (包括 Windows.h)
Library Kernel32.lib
DLL Kernel32.dll

另请参阅

DllMain

动态链接库函数

FindResource

FreeLibrary

GetProcAddress

GetSystemDirectory

GetWindowsDirectory

LoadLibraryEx

LoadResource

运行时动态链接

SetDllDirectory

SetErrorMode