LoadLibraryA 函数 (libloaderapi.h)

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

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

语法

HMODULE LoadLibraryA(
  [in] LPCSTR lpLibFileName
);

parameters

[in] lpLibFileName

模块的名称。 可以是库模块 (.dll 文件) ,也可以是可执行模块 (.exe 文件) 。 如果指定的模块是可执行模块,则不会加载静态导入;相反,模块就像由 LoadLibraryEx 使用 标志一 DONT_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 函数) 。 这样做可以在不将进程的已安装目录添加到 PATH 环境变量的情况下,找到与进程关联的专用动态链接库 (DLL) 文件。 如果指定了相对路径,则整个相对路径将追加到 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