window下的静态链接库和动态链接库

一、 介绍

本文意在讲解静态链接库与动态链接库的创建与使用,在此之前先来对二者的概念、区别及优缺点进行简要的阐述。其中大多内容参考相关网络资料,由于本人能力有限,不能确保完全准确无误,若有偏差之处请不吝指出。文中使用到的代码均在Visual Studio 2008中编译通过,如果您使用的IDE与本文不同,可根据实际情况进行相应项目创建与操作。希望本文内容对您有所帮助。

概念定义 分别编译与链接

大多数高级语言都支持分别编译(Compiling),程序员可以显式地把程序划分为独立的模块或文件,然后由编译器(Compiler)对每个独立部分分别进行编译。在编译之后,由链接器(Linker)把这些独立编译单元链接(Linking)到一起。链接方式分为两种:

静态链接方式:在程序开发中,将各种目标模块(.OBJ)文件、运行时库(.LIB)文件,以及经常是已编译的资源(.RES)文件链接在一起,以便创建Windows的.EXE文件。动态链接方式:在程序运行时,Windows把一个模块中的函数调用链接到库模块中的实际函数上的过程。 静态链接库与动态链接库

静态链接库(Static Library,简称LIB)与动态链接库(Dynamic Link Library,简称DLL)都是共享代码的方式。如果使用静态链接库(也称静态库),则无论你愿不愿意,.LIB文件中的指令都会被直接包含到最终生成的.EXE文件中。但是若使用.DLL文件,该.DLL文件中的代码不必被包含在最终的.EXE文件中,.EXE文件执行时可以“动态”地载入和卸载这个与.EXE文件独立的.DLL文件。

动态链接方式

链接一个DLL有两种方式:

载入时动态链接(Load-Time Dynamic Linking)

使用载入时动态链接,调用模块可以像调用本模块中的函数一样直接使用导出函数名调用DLL中的函数。这需要在链接时将函数所在DLL的导入库链接到可执行文件中,导入库向系统提供了载入DLL时所需的信息及用于定位DLL函数的地址符号。(相当于注册,当作API函数来使用,其实API函数就存放在系统DLL当中。)

运行时动态链接(Run-Time Dynamic Linking)

使用运行时动态链接,运行时可以通过LoadLibrary或LoadLibraryEx函数载入DLL。DLL载入后,模块可以通过调用GetProcAddress获取DLL函数的入口地址,然后就可以通过返回的函数指针调用DLL中的函数了。如此即可避免导入库文件了。

二者优点及不足 静态链接库的优点代码装载速度快,执行速度略比动态链接库快;只需保证在开发者的计算机中有正确的.LIB文件,在以二进制形式发布程序时不需考虑在用户的计算机上.LIB文件是否存在及版本问题,可避免DLL地狱等问题。 动态链接库的优点更加节省内存并减少页面交换;DLL文件与EXE文件独立,只要输出接口不变(即名称、参数、返回值类型和调用约定不变),更换DLL文件不会对EXE文件造成任何影响,因而极大地提高了可维护性和可扩展性;不同编程语言编写的程序只要按照函数调用约定就可以调用同一个DLL函数。 不足之处使用静态链接生成的可执行文件体积较大,包含相同的公共代码,造成浪费;(2)使用动态链接库的应用程序不是自完备的,它依赖的DLL模块也要存在,如果使用载入时动态链接,程序启动时发现DLL不存在,系统将终止程序并给出错误信息。而使用运行时动态链接,系统不会终止,但由于DLL中的导出函数不可用,程序会加载失败;使用动态链接库可能造成DLL地狱。DLL地狱

DLL地狱(DLL Hell)是指因为系统文件被覆盖而让整个系统像是掉进了地狱。

简单地讲,DLL地狱是指当多个应用程序试图共享一个公用组件时,如某个DLL或某个组件对象模型(COM)类,所引发的一系列问题。

最典型的情况是,某个应用程序将要安装一个新版本的共享组件,而该组件与机器上的现有版本不向后兼容。虽然刚安装的应用程序运行正常,但原来依赖前一版本共享组件的应用程序也许已无法再工作。在某些情况下,问题的起因更加难以预料。比如,当用户浏览某些web站点时会同时下载某个Microsoft ActiveX控件。如果下载该控件,它将替换机器上原有的任何版本的控件。如果机器上的某个应用程序恰好使用该控件,则很可能也会停止工作。

在许多情况下,用户需要很长时间才会发现应用程序已停止工作。结果往往很难记起是何时的机器变化影响到了该应用程序。

明天又会是新的一天,而我依然年轻。

window下的静态链接库和动态链接库

相关文章:

你感兴趣的文章:

标签云: