VC DLL(1)
VC DLL(1)
DLL全名为:dynamic link library,就是动态链接库的意思。在安装软件的时候大家应该经常能看到各种文件后缀为.dll的文件,就是用于程序执行时进行动态链接的。那么为什么要使用动态链接?
在最初,C/C++程序使用的是静态链接。也就是我们在写代码的时候,使用多个文件。一旦需要什么函数,就将其包含进来,然后调用其中的函数。这样的连接方式就是将函数代码一起连接到可执行文件中,程序被调用时统一复制到内存中,实现调用。而动态链接,顾名思义,就是在程序运行阶段将程序代码附加到进程地址空间中,再实现调用。
为何要使用动态链接?我们知道,将文件加载到内存是需要时间的,如果在程序初期统一将程序代码加载到内存中,显然效率更高。在软件设计的初期阶段确实是这样,但是随着系统功能的增强,软件体积的增加,用这种方式编译出来的程序体积偏大,而且程序和程序之间会存在大量的重复代码。这个很显然是不必要的,浪费空间。根据经典的时间&空间难以兼得的理论,出现了动态链接,也就是运行时连接。在系统目录下,就存在大量的dll文件,这些文件就是为了各种函数功能而准备的。
另外需要强调的一点就是,每个被加载到内村中的DLL都只有一份。不是两个程序都加载了同一个Dll后都会导致内存中出现两份一样的DLL文件。这里Dll文件加载后存在一个使用计数。在一个Dll第一次被加载到Dll后这个使用计数的值为1,之后每被加载一次都会递加这个值(相信熟悉句柄的同学对这个应该比较了解,C++沉思录中讲的比较明白~)。如果Dll被释放,这个值就会递减,一旦使用计数的值为0,系统就会将这个Dll从内存中卸载。
那么如何创建自己的DLL?在VC中,我们能够很方便的创建一个DLL工程。我所使用的编译器是VS2010。
Dll工程创建步骤暂时是没时间去截图了,下一期中再写出来。工程创建完成后,会得到下面的几个文件(win32 dll):
其中我们主要需要关注的就是MyLib.h和MyLib.cpp。这两个文件分别包含了函数的声明和函数的实现。其中很需要关注的是文件中的函数声明:
(位于MyLib.h)
其中很有意思的就是__declspec(dllexport)和__declspec(dllimport),括号中的意思分别是导出和导入。而且使用了一个条件编译,由此可见这个文件还有其他用途。截图中能够看到,#else下面的那句宏定义是灰色,表示的意思就是这个现在是无效的,所以现在这个文件编译出来的函数是用来导出的。
在MyLib.cpp中对应着函数的实现:
也很简单,就是返回一个值为42的整数。这个生成的文件是没有任何问题的,所以可以直接编译出来一个完整的Dll文件。工程编译完成后,会得到如下的几个文件,在debug文件夹中:
如果是使用隐式载入,那么需要dll和lib这两个文件,但如果是显示载入的话。那么只需要dll文件,以及对dll工程中需要使用的函数的原型就可以了。
所谓隐式载入,就是直接让执行程序包含引用Dll中所包含的全部符号(函数原型,变量名等)使得在加载程序中隐式的载入所需的Dll。
而显示载入,在VC中,则是使用LoadLibrary()来获取Dll文件的句柄,再使用GetProcAddress函数来获取相应的函数地址,从而使用dll中的函数。另外需要注意的是,在使用显示载入后,需要再不需要Dll的时候调用FreeLibrary函数显示卸载Dll。
在下一周中,我将比较详细的把Dll加载到可执行文件中进行一个简单的演示,以及做一个Dll工程的创建的图解。
另外以及为什么隐式载入需要两个文件而显示载入只需要一个文件进行较为详细的解释。
数字信号处理的作业还没写,蛋疼啊……