动态链接库是什么,为什么要用动态链接库
dll是文件,是二进制文件,是可执行文件。所谓可执行文件就是可以控制OS执行的,其实就是一堆CPU指令。但是dll不是能被windows直接执行,其实CPU是可以执行任何有效指令的,windows不能直接执行是因为windows的shell可以直接实行*.exe文件,没有必要在多一个*.dll。既然已经有可以直接执行的*.exe了,那么为什么要有可间接执行的*.dll呢?原因很多:
- 由于每个exe是运行都是一个进程,而进程之间是有严格的界限的,这样就产生了一个问题,很多很多的程序里面包括了一些相同功能的函数,尽管进程地址空间都是独立的,但为每个程序文件链接相同的代码显然是一种浪费。
- 我们都知道软件开发的一个重要原则就是模块相对独立,接口清晰。为此,我们在编写源文件时使用很多方法,不管是C语言众多的头文件和源文件,还是C++的类封装,这还专门有一门学问叫做《设计模式》,这种种都是为了两个字——清晰!然而最后编译链接的成果就是一个exe文件,显然这是和软件设计相悖的。dll很好地解决了这个问题,一个dll是一个相对独立的模块,当程序只需要改动一个模块时,只要替换一个新的dll。只要设计的好,dll间也存在层次结构,那么更新一套软件就可以精确地定位模块,到底需要替换多少dll。
动态链接库怎么用
dll主要有两种用法:
- 一般编译器在编译链接dll时,会有两个产物,一个lib(静态链接库),一个dll。lib用于将.h文件中声明的函数定位到dll。这样,使用时就只要把.h .lib添加到工程(VC),直接使用函数名引用函数,编译器遇到这样的函数调用时会让它通过编译,因为.lib在链接时说明了“该函数再某个dll中”^_^
- 没有.h和.lib文件时,一样可以引用dll中的函数,如果知道函数原型,那么LoadLibrary和GetProcAddress可以得到函数的指针,然后就可以调用
- 调用M$未公开的函数,SDK开发包介绍了大量函数,但并不是全部,依然有相对部分函数是没有文档说明的,一般是微软内部使用的。然而有时一些特殊的用途,我们需要调用未公开函数。再开发VxD时,就经常要调用kernel32.dll中的未公开函数
- 有的函数再dll中没有名字,这也是可以调用的,因为没有名字会有一个标识的ID,调用时在以上步骤中GetProcAddress的第二个参数用MAKEINTRESOURCE宏转换一下
...
OpenVxDHandle ... HMODULE hKernelModule; HANDLE hEvent; DOWRD KernEvent; hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); hKernelModule=::LoadLibrary("KERNEL32.DLL"); if(hKernelModule==NULL) { return NULL; } OpenVxDHandler=(OPENVXDHANDLE)GetProcAddress(hKernelModule,"OpenVxDHandle"); if(OpenVxDHandler==NULL) { FreeLibrary(hKernelModule); return NULL; } KernEvent=(*OpenVxDHandler)(hEvent); FreeLibrary(hKernelModule);
typedef void (WINAPI* RUN)(HWND, HICON, LPCSTR, LPCSTR, LPCSTR, UINT); HMODULE hShell32; RUN RunFileDlg; hShell32 = LoadLibrary("shell32.dll"); RunFileDlg = (RUN)GetProcAddress(hShell32, MAKEINTRESOURCE(61)); RunFileDlg(hParent, hIcon, NULL, NULL, NULL, 0); FreeLibrary(hShell32);
这段代码就是去调用shell的运行对话框