的C/C++运行期库能够释放它用于管理多线程应用程序的数据块。
注意:DLL 能够防止线程终止运行。例如,当DllMain()函数接收到DLL_THREAD_DETACH 通
知时,它就能够进入一个无限循环。只有当每个DLL 已经完成对DLL_THREAD_DETACH
通知的处理时,cāo作系统才会终止线程的运行。
如果当DLL 被撤消时仍然有线程在运行, 那么就不会有任何线程调用带有
DLL_THREAD_DETACH 值的DllMain()函数。可以在进行DLL_THREAD_DETACH 的处理
时查看这个情况,这样就能够执行必要的清除cāo作。
10.2.2 DLL 的导出函数
当Microsoft 的C/C++编译器看到变量、函数原型或C++类之前的这个修改符的时候,它
就将某些附加信息嵌入产生的.obj 文件中。当链接DLL 的所有.obj 文件时,链接程序将对这
些信息进行分析。
枫叶文学网www.fywxw.com
Visual C++ 6.0 程序设计从入门到精通
·256·
当DLL 被链接时,链接程序要查找关于输出变量、函数或C++类的信息,并自动生成
一个.lib 文件。该.lib 文件包含一个DLL 输出的符号列表。当然,如果要链接引用该DLL 的
输出符号的任何可执行模块,该.lib 文件是必不可少的。除了创建.lib 文件外,链接程序还要
将一个输出符号表嵌入产生的DLL 文件。这个输出节包含输出变量、函数和类符号的列表(按
字母顺序排列)。该链接程序还将能够找到每个符号的相对虚拟地址(RVA),并在该地址中
放入DLL 模块。
使用Microsoft 的Visual Studio 的DumpBin.exe 实用程序(带有-exports 开关),能够看到
DLL 的输出节是个什么样子。Kernel32.dll 的输出结果如图10-1 所示。
图10-1 dumpbin 输出动态链接库的导出函数
通过Visual Studio 所提供的Dependency Walker 的可视化工具也可以查看动态链接库的
导出函数信息,如图10-2 所示。
图10-2 利用Dependency Walker 工具查看导出函数信息
枫叶文学网www.fywxw.com
第10 章 动态链接库
·257·
10.3 两种链接DLL 的方式
如果线程需要调用DLL 模块中的函数,那么DLL 文件映像必须映shè到调用线程的进程
地址空间中。可以用两种方法进行这项cāo作。第一种方法是让应用程序的源代码只引用DLL
中包含的符号。这样,当应用程序启动运行时,加载程序就能够隐含加载(或链接)需要的
DLL。第二种方法是在运行时让应用程序显式加载需要的DLL 并且显式链接到需要的输出符
号。换句话说,当应用程序运行时,其中的线程决定它是否要调用DLL 中的函数。该线程可
以将DLL 显式加载到进程的地址空间,获得DLL 中包含的函数的虚拟内存地址,然后使