动态连接库(dll)生成及应用程序载入dll过程分析

来源:互联网 发布:unity3d 动画 编辑:程序博客网 时间:2024/06/06 00:31
本文主要是解决大家对于应用程序使用dll的幕后细节进行讲解,其他很多细节在此不再多提,假设读者已经明白如何编写dll,若对此不甚明白可参看下文:

http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx

 

动态链接库的生产过程

1.生成lib文件

2.生成dll文件

应用程序载入dll过程

1.链接

2.载入dll

3.修复导入符号的地址

 

 

动态链接库的生产过程:

1.生成lib文件

      dll生成的过程中会将该dll要导出的符号,包括函数名,变量名,类等名称输出到相应的lib文件的Exports段中,使用visual studio自带的dumpbin,  使用exports参数输出lib的exports段,即可输出如下信息:

dumpbin  –exports xyzLibrary.lib


图1. Lib文件dump输出的Exports段


         该lib文件exports段显示,导出了两个符号,即GetXyz和_GetXyz@0

 

2.生成dll文件

      当然动态连接库的实际内容都是包含在dll文件中的,而为了使用户能够使用dll中的函数,变量,以及类等信息,dll会在文件的exports段中列出将该dll要导出的符号,包括函数名,变量名,类等名称及其相对偏移地址。

      如 dumpbin  -exports  xyzLibrary.dll输出信息如下:



图2.dll文件dump输出的exports段


       输出信息显示,该dll导出了两个符号,GetXyz, 偏移地址为00001030,以及_GetXyz@0, 偏移地址为00001030,两个符号偏移地址一样,说明这两个符号是同一个函数,只是导出了两个名字而已。

 

应用程序载入dll过程:

1.链接

      链接过程中,编译器会根据符号去应用程序的依赖的lib文件中去找,若找到该符号就把相应的dll文件名和符号名写入exe的imports段中,若没找到,编译器就会报unresolved extern symbols之类的错误,最后编译成功的exe文件的imports段是该exe依赖的dll和符号列表,使用dumpbin输出xyzExecutable.exe的imports段信息如下:

Dumpbin  -imports  xyzExecutable.exe



图3.exe文件的imports段信息


       信息显示该exe从xyzLibrary.dll文件中导入了_GetXyz@0符号。

 

2.载入dll

 

      当exe被装载程序载入内存,并创建进程后,装载程序会将exe依赖的dll也载入程序的虚拟地址空间中,先会按照一个顺序扫描寻找该dll文件,具体顺序大概是先系统目录,再当前目录,若扫描完找不到dll文件,则会弹出对话框报错,如下图所示:

图4.应用程序找不到依赖的dll出错窗口


       当然这个载入过程是会嵌套的,比如程序a导入了dll_b, 但是dll_b还可能依赖dll_c,这样载入器在载入dll_b时也会将dll_c也载入的。

 

3.修复导入符号的地址

 

         装载程序找到这个dll后,将其载入到相应进程的地址空间,然后就要去dll的文件的exports段搜寻所依赖的符号,然后计算该符号的绝对地址,即dll的地址 + 符号相对dll首地址的相对地址,再使用这个符号去修复exe中对该符号的所有引用,但是如果在dll中没有找到相应符号,则会弹出以下错误窗口:



图5.应用程序在相应dll中找到不到相应的符号出错窗口

 

         dll的生成和应用程序载入dll的过程大概就是这样了,也不知道对大家会不会有帮助,但是做为我自己的学习笔记是可以了。


原创粉丝点击