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的过程大概就是这样了,也不知道对大家会不会有帮助,但是做为我自己的学习笔记是可以了。