1、为什么要讲动态链接库,它和excel插件有什么关系。
2、什么是动态链接库,它们都有哪几类。
动态链接库和普通exe应用程序有什么区别。
3、如何编写动态链接库。
3.1、如何声明函数
3.2、如何导出函数,导出类。
3.3、编写一个简单的动态链接库
4、如何调用动态链接库。
5、如何调试动态链接库。
6、查看动态链接库的内容。
1、 为什么我们要讲动态链接库
一句话就是excel插件就是一个动态链接库,它和普通动态链接库除了功能之外,在形式上几乎没什么大的区别,它们的主要区别是:
² xll文件中必须包含几个excel调用要求的几个函数
² 必须导出excel调用的函数,而其它dll不是必须的
² Excel插件扩展名最好为xll,其实扩展名是什么并没什么关系,写成xll也是为了好区别。
可以这么认为,excel插件就是一种特殊的动态链接库。
2、 什么是动态链接库
动态链接库在MSDN里面定义是一个文件,一个包含了一个或多个被编译了的函数的文件。其实动态链接库是一个封装了一些可以被其它应用程序共享的程序、数据以及资源的程序库。动态链接库的出现使大型系统更容易被划分为多个模块。动态链接是一种程序调用方法,通过动态链接我们可以使用公用的程序模块,甚至可以调用其它软件中的程序。它提供了一种开发可重用模块的有效方法。通常把一些可能被其它一个或多个应用程序调用的程序模块封装在一起,然后编译链接成库。动态链接库文件的扩展名一般是dll,也有可能是drv和sys等,当然也可以自定义其它扩展名,只要文件的格式在正确即可。在dll中每个函数都含有完整的可执行代码,但它们不可以单独执行,只能在其它应用程序调用时执行。因为它缺少自己的堆栈空间。也正因此,一个dll可以被多个应用程序同时使用,应用程序在调用它时是把它映射到自己的进程空间,并使用应用程序的自己的堆栈空间。
那既然有动态链接,那是否有静态链接呢,回答是肯定的。动态链接就是相对于静态连接而言的。所谓静态链接是在编译链接时把要调用的程序代码的副本复制到调用程序中,成为调用程序自身的一部分,而在执行时应用程序也不再需要静态链接库了。所以当一个静态库被多个程序使用时,每个程序内部都会包含一个相应函数的副本,导致应用程序文件较大,在执行时也会占用更多内存。而动态链接库并没有把函数代码的副本复制到应用程序的内部,仅仅是保存了函数所在的地址,不会占用多少空间。在执行时应用程序也只是把动态库映射到自己的进程空间,并不会在内存中生成多个副本。那么同一个DLL副本在内存中被多个程序调用会不会像会影响呢?对于普通的开发人员来说大可不必担心,win32系统会为我们处理这个过程。
通常情况下,当应用程序调用dll时,win32系统首先把dll调入到系统的全局堆栈中,然后通过内存映射文件,让每个调用进程都有该dll的一份影像。
动态链接库与静态链接库的比较:
|
动态链接库 |
静态链接库 |
可否单独执行 |
否 |
否 |
调用程序以何种方式调用其中函数 |
通过使用函数的地址 |
复制副本到调用程序 |
被多个程序调用时,在内存中的存在方式 |
单个副本 |
多个副本 |
应用程序链接过程 |
在调用时才链接 |
在生成应用程序时链接 |
通常文件扩展名 |
Dll、sys等 |
LIB |
是否可以被其它语言调用 |
可以 |
否 |
Windows本身就含有大量的dll,下表将说明 Win32 API 中几个常用的 DLL。
DLL |
内容说明 |
GDI32.dll |
用于设备输出的图形设备接口 (GDI) 函数,例如用于绘图和字体管理的函数。 |
Kernel32.dll |
用于内存管理和资源处理的低级别操作系统函数。 |
User32.dll |
用于消息处理、计时器、菜单和通信的 Windows 管理函数。 |
综上所诉使用动态链接库较静态链接库有许多优点。使用dll不仅可以节省内存,减少交换操作,也节省磁盘空间,试想下如果在win32系统中每个应用程序都包含一个实现windows的基本功能的副本那将是什么样的情景。使用dll可以降低维护以及升级成本。总结起来它有如下一些优点:
² 节省内存:dll在内存中只有一个副本,而使用静态链接库的应用程序在内存中都会加载一个代码副本。
² 节省磁盘空间:对于使用dll的程序,它自身内部并不保存dll的副本,在磁盘上只要有一个副本就可以了,但是对于使用静态库的程序,每个程序内部都有一个代码副本,那如果你的程序中把gdi32.dll、user32.dll等基本的windows功能实现的代码都包含进程序内部,那你的单个程序就可能大到几百兆。下图显示了一个简单应用程序testapp.exe所调用的dll,正是有这些dll的支持,几K字节的程序就能够拥有丰富的功能。
² 可以降低升级维护的成本。在对软件系统进行升级维护时,只要不更改调用接口,修改dll中的代码不会对调用它程序产生任何影响。而静态链接库则没有如此方便,只要它自身代码被改变,那所有调用它的程序都需要重新编译链接。
² Dll可以被多种语言调用:无论是何种语言编写的应用程序,只要它遵循dll的函数的调用约定,就可以调用此dll。关于dll的调用约定在后面章节中将详细介绍。
² 可以扩展MFC库的功能:通过创建MFC扩展dll,可以从现有 MFC 类派生类,创建具有扩展功能的MFC动态库,以供MFC应用程序使用。
² 创建纯资源dll:我们可以创建具有某种国家语言的资源dll,通过调用不同的资源dll就可以轻松实现具有多国语言的应用程序。
动态链接库也是程序,它与可执行应用程序除了在使用时能否单独执行的区别外,它们内部还是有有些本质的区别,下面的表中列出了动态链接库于普通应用程序的一些区别:
|
动态链接库 |
应用程序 |
可否单独执行 |
否 |