Visual Studio C++动态链接:DLL导入库.lib内容及函数解析机制问询
Visual Studio C++ 动态链接问题解答
问题1:创建动态库时生成的library.lib文件,是否包含指向动态库对应函数的内存位置引用?
- 首先要明确:动态库编译生成的
.lib是导入库(Import Library),和静态库的.lib本质完全不同,不包含任何实际的函数实现代码,也不会存储动态库函数运行时的内存位置引用。 - 核心原因是:DLL加载到进程虚拟地址空间的基地址是操作系统加载器在运行时动态决定的,编译生成
.lib的阶段完全无法预判后续DLL的加载位置,不可能提前存储内存引用。
问题2:可执行程序在加载时或运行时,具体是如何查找并解析动态库函数的?
分两种常见的链接场景说明:
隐式链接(使用导入库的常规场景)
- 程序启动时,Windows的PE(可移植可执行文件)加载器会先读取EXE文件结构中的导入表,拿到需要加载的DLL名称列表
- 加载器按照标准Windows DLL搜索顺序查找对应DLL文件:优先搜索进程当前工作目录,其次依次查找系统目录(
C:\Windows\System32)、Windows目录(C:\Windows)、环境变量PATH中配置的目录 - 找到DLL后将其加载到进程的虚拟地址空间,再读取DLL的导出表,匹配导入表中记录的函数名称/序号,拿到函数的实际内存地址,填充到EXE的*导入地址表(IAT)*中
- 后续程序调用对应DLL函数时,会直接读取IAT中存储的内存地址跳转执行
显式链接(开发者手动加载DLL的场景)
- 不需要提前链接导入库,由开发者在代码中主动调用
LoadLibrary/LoadLibraryW加载指定路径的DLL - 调用
GetProcAddress传入要获取的函数名/导出序号,直接从已加载DLL的导出表中查询得到函数内存地址,开发者自行存储该地址后即可调用 - 使用完成后调用
FreeLibrary卸载DLL即可
问题3:DLL导入库(.lib文件)中具体包含哪些内容,是否是它提供了解析动态库函数的相关指令?
导入库的核心内容:
- 对应DLL的文件名字符串
- 该DLL所有导出函数的符号名、可选的导出序号
- 供链接器使用的重定位辅助信息
作用说明:
- 导入库只在编译链接生成EXE的阶段生效,作用是给链接器提供足够的信息,让链接器能在最终生成的EXE PE结构中写入正确的导入表条目,标注清楚需要加载的DLL名称、需要解析的函数列表
- 它本身不提供任何运行时的函数解析指令,运行时的DLL查找、函数地址解析逻辑完全由Windows操作系统的PE加载器负责,程序运行阶段不需要用到对应的
.lib文件,只需要DLL文件即可。
内容的提问来源于stack exchange,提问作者Yogi Bear
相关产品推荐
相关产品推荐

