动态链接库DLL编程.ppt
《动态链接库DLL编程.ppt》由会员分享,可在线阅读,更多相关《动态链接库DLL编程.ppt(61页珍藏版)》请在三一办公上搜索。
1、,VC+动态链接库(DLL)编程,1.概论,先来阐述一下DLL(Dynamic Linkable Library)的概念,你可以简单的把DLL看成一种仓库,它提供给你一些可以直接拿来用的变量、函数或类。在仓库的发展史上经历了“无库静态链接库动态链接库”的时代。对动态链接库,需建立如下概念:,(1)与具体的编程语言及编译器无关,只要遵循约定的DLL接口规范和调用方式,用各种语言编写的DLL都可以相互调用。譬如Windows提供的系统DLL(其中包括了Windows的API),在任何开发环境中都能被调用,不在乎其是Visual Basic、Visual C+还是Delphi。,(2)动态链接库随处
2、可见,在Windows目录下的system32文件夹中会看到kernel32.dll、user32.dll和gdi32.dll,windows的大多数API都包含在这些DLL中。kernel32.dll中的函数主要处理内存管理和进程调度;user32.dll中的函数主要控制用户界面(MessageBox函数);gdi32.dll中的函数则负责图形方面的操作。,(3)VC动态链接库的分类,Visual C+支持三种DLL,它们分别是非MFC动态库、MFC规则DLL、MFC Extension DLL。非MFC动态库不采用MFC类库结构,其导出函数为标准的C接口,能被非MFC或MFC编写的应用程序
3、所调用;MFC规则DLL 包含一个继承自CWinApp的类,但其无消息循环;MFC扩展DLL采用MFC的动态链接版本创建,它只能被用MFC类库所编写的应用程序所调用。,2.静态链接库,在VC+6.0中new一个名称为libTest的static library工程,并新建lib.h和lib.cpp两个文件,lib.h和lib.cpp的源代码如下:/文件:lib.h#ifndef LIB_H#define LIB_H extern C int add(int x,int y);/声明为C编译、连接方式的外部函数#endif/文件:lib.cpp#include lib.h int add(int
4、 x,int y)return x+y;,#include#include.lib.h#pragma comment(lib,.debuglibTest.lib)/指定与静态库一起连接 int main(int argc,char*argv)printf(2+3=%d,add(2,3);,选择tools、options、directories、library files菜单或选项,填入库文件路径,4.非MFC DLL,在建立的工程中添加lib.h及lib.cpp文件,源代码如下:,/*文件名:lib.h*/#ifndef LIB_H#define LIB_Hextern C int _decl
5、spec(dllexport)add(int x,int y);#endif/*文件名:lib.cpp*/#include lib.hint add(int x,int y)return x+y;,dllCall,#include#include typedef int(*lpAddFun)(int,int);/宏定义函数指针类型int main(int argc,char*argv)HINSTANCE hDll;/DLL句柄 lpAddFun addFun;/函数指针 hDll=LoadLibrary(.DebugdllTest.dll);if(hDll!=NULL)addFun=(lpAd
6、dFun)GetProcAddress(hDll,add);if(addFun!=NULL)int result=addFun(2,3);printf(%d,result);FreeLibrary(hDll);return 0;,DLL的调用和静态链接库的调用有较大差异,首先,语句typedef int(*lpAddFun)(int,int)定义了一个与add函数接受参数类型和返回值均相同的函数指针类型。随后,在main函数中定义了lpAddFun的实例addFun;其次,在函数main中定义了一个DLL HINSTANCE句柄实例hDll,通过Win32 Api函数LoadLibrary动态
7、加载了DLL模块并将DLL模块句柄赋给了hDll;再次,在函数main中通过Win32 Api函数GetProcAddress得到了所加载DLL模块中函数add的地址并赋给了addFun。经由函数指针addFun进行了对DLL中add函数的调用;最后,应用工程使用完DLL后,在函数main中通过Win32 Api函数FreeLibrary释放了已经加载的DLL模块。,声明导出函数,DLL中导出函数的声明有两种方式:一种为给出的在函数声明中加上_declspec(dllexport);一种方式是采用模块定义(.def)文件声明;,在DLL中想要export的函数和数据定义前添加_declspec
8、(dllexport)关键字(对于函数和变量定义,加在最前面;对于class定义,加在class关键字后);_declspec(dllexport)void ShowDlg(void)class _declspec(dllexport)class_name/导出类 这样该函数和数据就会被添加到ET中。使用这种方法函数将按名字export。,_declspec(dllexport),(.def)文件声明,为DLL创建一个.DEF文件(模块定义文件),并在build该DLL时使用这个.DEF文件。使用这种方法使你可以将函数按序号export。在LINK选项卡中假如:/def:lib.def将lib
9、.def加入到工程中。,lib.def,;lib.def:导出DLL函数LIBRARY dllTestEXPORTSadd 1.def文件的规则为:(1)LIBRARY语句说明.def文件相应的DLL;(2)EXPORTS语句后列出要导出函数的名称。可以在.def文件中的导出函数名后加n,表示要导出函数的序号为n(在进行函数调用时,这个序号将发挥其作用);(3).def 文件中的注释由每个注释行开始处的分号(;)指定,且注释不能与语句共享一行。,库的调试与查看,动态链接库中的导出接口可以使用Visual C+的Depends工具进行查看,用Depends打开系统目录中的MouseHook.dl
10、l.,DLL的调用方式,隐式调用:将DLL工程生成的.lib文件和.dll文件拷入当前工程所在的目录,并在*.cpp文件(的顶部添加:#pragma comment(lib,RegularDll.lib)OR,动态调用,特点:是完全由编程者用 API 函数加载和卸载 DLL,程序员可以决定 DLL 文件何时加载或不加载,显式链接在运行时决定加载哪个 DLL 文件。,dllTest.dll,在建立的工程中添加lib.h及lib.cpp文件,源代码如下:/*文件名:lib.h*/#ifndef LIB_H#define LIB_Hextern C int _declspec(dllexport)a
11、dd(int x,int y);#endif/*文件名:lib.cpp*/#include lib.hint add(int x,int y)return x+y;,调用 dllTest.dll,#include#include typedef int(*lpAddFun)(int,int);/宏定义函数指针类型int main(int argc,char*argv)HINSTANCE hDll;/DLL句柄 lpAddFun addFun;/函数指针hDll=LoadLibrary(.DebugdllTest.dll);if(hDll!=NULL)addFun=(lpAddFun)GetPr
12、ocAddress(hDll,add);if(addFun!=NULL)int result=addFun(2,3);printf(%d,result);FreeLibrary(hDll);,DLL的Export和Import,DLL的export是指将DLL中的函数和数据输出到其它程式中,以供其使用。DLL的import是指使用DLL的程式引入DLL中的函数和数据。DLL的export DLL中包含有一个表,称为export table(以下简称ET),其中包含了DLL中可以被外部程式使用的所有函数和数据的名字。只有记录在ET中的函数和数据才可以被外部程式所使用(如果没有.DEF文件的话),
13、其它所有没有记录在ET中的函数和数据都被视为是DLL私有的。,DllMain函数,Windows在加载DLL的时候,需要一个入口函数,就如同控制台或DOS程序需要main函数、WIN32程序需要WinMain函数一样。在前面的例子中,DLL并没有提供DllMain函数,应用工程也能成功引用DLL,这是因为Windows在找不到DllMain的时候,系统会从其它运行库中引入一个不做任何操作的缺省DllMain函数版本,并不意味着DLL可以放弃DllMain函数。,BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOI
14、D lpReserved)DllMain函数在DLL被加载和卸载时被调用,在单个线程启动和终止时,DLLMain函数也被调用;ul_reason_for_call指明了被调用的原因。原因共有4种,即PROCESS_ATTACH、PROCESS_DETACH、THREAD_ATTACH和THREAD_DETACH,以switch语句列出。,DLL导出变量,/*文件名:lib.h*/#ifndef LIB_H#define LIB_Hextern int dllGlobalVar;#endif/*文件名:lib.cpp*/#include lib.h#include int dllGlobalVa
15、r;BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)dllGlobalVar=100;/在dll被加载时,赋全局变量为100 return TRUE;,;文件名:lib.def;在DLL中导出变量LIBRARY dllTestEXPORTSdllGlobalVar DATA,在主函数中引用DLL中定义的全局变量:,#include#pragma comment(lib,dllTest.lib)extern int _declspec(dllimport)dllGlobalVar;/用
16、_declspec(dllimport)导入int main(int argc,char*argv)printf(%d,dllGlobalVar);dllGlobalVar=1;printf(%d,dllGlobalVar);return 0;,特别要注意,用extern int dllGlobalVar声明所导入的并不是DLL中全局变量本身,而是其地址,应用程序必须通过强制指针转换来使用DLL中的全局变量。这一点,从*(int*)dllGlobalVar可以看出。因此在采用这种方式引用DLL全局变量时,千万不要进行这样的赋值操作:dllGlobalVar=1;,MFC规则DLL,MFC规则D
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 动态 链接 DLL 编程
链接地址:https://www.31ppt.com/p-6101028.html