跳到主要内容

DLL的导入库中是什么信息

· 阅读需 3 分钟

当我们在项目中使用DLL时,链接器需要查找DLL输出的变量、函数或C++类等符号信息,并自动生成一个对应的.lib文件。这个.lib文件被称为导入库,它包含了DLL输出的符号列表。如果一个可执行模块需要引用DLL中的符号(使用GetProcAddress除外),则必须链接该导入库。

导入库中包含的信息

实际上,导入库中并不包含符号的相对虚拟地址(RVA)。它仅仅是一些符号以及与其相关的元数据,例如该库对应的DLL的名称等。(这是我当前的理解,欢迎探讨)。

应用程序如何调用DLL中的函数

当一个应用程序通过导入库调用DLL中的函数时,这个过程是在进程的主线程开始运行之前由加载器完成的。

加载器按照可执行文件的输入节中指定的DLL名称,通过Windows的搜索路径找到并加载对应的DLL。加载成功后,DLL被映射到进程的地址空间中,此时,加载器根据DLL的实际加载地址和符号信息,将每个输入节中的符号地址填入可执行模块的输入节中,完成动态链接。

这一过程解释了为什么可以使用lib命令通过.def文件生成导入库。

使用def文件生成lib文件的示例

以下是一个完整的操作流程:

1. 创建一个.def文件

LIBRARY
xujian.dll
EXPORTS
xujian

2. 使用lib命令生成.lib文件

运行以下命令生成导入库:

lib /def:XX.def /machine:i386 /out:XX.lib

3. 编写一个测试程序

在工程文件中加入生成的XX.lib后,编写如下代码:

extern "C" void xujian();

int main()
{
xujian();
return 0;
}

编译和链接后,程序应该可以正常运行。