动态链接库DLL - 中国科学技术大学
- 格式:doc
- 大小:133.50 KB
- 文档页数:14
动态链接库DLL目录动态链接库DLL (1)目录 (1)DLL概述 (3)DLL定义 (3)DLL的种类 (3)动态链接库和静态链接库的比较 (3)DLL的特点: (3)DLL的基本理论 (4)DLL入出口函数 (4)DLL的链接方式 (4)隐式连接 (4)显式链接DLL (6)DLL动态链接库库函数的导出 (11)从DLL中导出数据变量 (12)用VC++开发环境生成DLL (13)用VC++生成WIN32 DLL (13)用VC++的MFC生成的DLL (13)使用DLL (14)DLL的使用 (14)DLL的调试 (14)DLL概述DLL特点:要求一个DEF文件;要求一个DllMain()的入口点,不是WinMain();DLL可以装入,但不能执行。
DLL定义动态链接库:是应用程序中的一段程序,将它放在一个不同的容器内,是一个可以从主.exe 文件中单独执行的模块.可以认为一个DLL就是其它应用程序在执行时,能够动态链接和调用的一组服务或函数.DLL中存放的一般是一些公共的子程序段或各种资源和数据.一个最大的特点:可以实现应用程序本地化.如在DLL中封装了各种语言,在安装时进行适当的选择就能实现本地化.DLL的种类主要有Win32 DLL和MFC APPWizard DLL两大类及相关子类。
动态链接库和静态链接库的比较动态链接:在应用程序中不需要包含所要调用函数的代码,而只需要所调DLL函数的一些信息,如DLL位置及相应的函数名。
与函数的链接到编译或运行时进行。
静态链接:应用程序必须从静态链接库中取得所需调用函数的代码,并把这些代码放在应用程序的可执行代码中。
如一般的库函数调用则属此类。
DLL的特点:•有利于不同的应用程序共享数据和资源;•多个应用程序可以使用内存中的动态链接库的单一映射,从而节约了程序运行和内存空间;•通过使用动态链接库,应用程序可以拆分为相对独立的功能模块,有利于应用程序的升级;•当多个应用程序需要使用相同的函数时,通过使用动态链接库,可以节约大量的硬盘空间。
DLL的基本理论应用程序在使用DLL中的内容之前,系统要调用入出口函数完成DLL的初始化和终止工作。
DLL入出口函数1、DllMain函数:在一个DLL的调用和撤除时被调用,一般发生在应用程序使用LoadLibrary 和FreeLibrary等函数及进程经线程启动和终止时。
函数结构为:其中hInstance是DLL的模块句柄, lpvReserved 指定DLL初始化和清除的一些内容指在MFC的DLL使用中,已编好了DllMain()函数,用户不必写,在装载DLL时调用其成员函数InitInstance,在DLL退出时调用成员函数ExitInstance, 所需要的初始化和终止工作在这两个函数中完成.DLL的链接方式DLL中包含一个或多个函数,调用这些函数的过程和编译,链接的方式包括显式连接和隐式链接。
隐式连接!!原理:先说明DLL的导入库文件(lib),因在库文件包含了一系列指向动态链接库的指针.应用程序通过库文件和DLL链接,调用DLL中的函数.●应用程序在调用DLL时需以下信息:1.包含导出函数以及类声明的头文件,需要知道函数名和函数接口信息.2.DLL的导入库文件,应用程序在编译链接需要.3.实际的DLL文件,应用程序在运行时调用它.●具体做法:●第一步,代码声明。
有几种导出成员函数的方法用extern进行修饰,实例代码如下:或者:(后者专门针对动态链接库,效率更高)或者:使用dll生成方提供的头文件。
●第二步,添加Link库文件Dll文件生成的同时,一个.lib链接库文件也会生出。
其功能是间接调用者的程序和dll 文件,它描述了dll的基本状况。
●第三步:部署dll文件到调用者能找到的位置。
显式链接DLL●原理:应用程序在运行时通过函数调用来显式装载和卸载DLL,并通过函数指针来调用DLL的导出函数,这种方式主要用于灵活控制DLL库动态装入和装出的场合.●使用:第一步:调用函数LoadLibrary或AfxLoadLibrary装载DLL并得到模块句柄.原型如下: HINSTANCE LoadLibrary(LPCSTR lpLibFileName);参数为要装入的DLL的文件名字.当此函数被多次调用时,在进程中只有一份DLL程序和数据,系统通过计数器来标识.第二步:调用函数GetProcAddress来获得导出函数的指针.函数原型如下:FARPROC GetProcAddress(HMODULE hModul,LPCSTR lpProName);hMoudul是DLL的实例句柄,参数lpProName是相应的函数名。
第三步:在使用完后调用函数FreeLibrary或AfxFreeLibrary 来释放DLL. FreeLibrary原型为BOOL FreeLibrary(HINSTANCE hInstLib);参数是装入的DLL模块的句柄,调用一次,DLL计数器值减一,最终回到0,系统释放被DLL占用的空间。
●好处:a)不需要其它文件(例如link时的.lib文件);b)速度较快,但耗费资源Code:Note:GetProcAddress方法因为是运行时载入,没有编译名字改编,所有使用的名字必须是dll中的改编后的名字。
最好是都不改。
关于头文件1,dll生成者不一定需要,可以提供给使用dll的client,因为他们一般不知道dll内部有哪些函数和变量可以使用,因而在他们的程序内定义变量和函数比较麻烦。
2,当然,这个头文件也可以供dll生成者使用,以提供一些辅助功能。
这样.h文件同时供dll生成方和调用者使用,而两者可以实现不同的功能。
例如:头文件:源文件:成员类的导出和导入导出:在头文件中定义,然后再实现头文件dll1.h源文件dll1.cpp调用:更新头文件,lib文件,dll文件,然后实现调用代码:导出类的部分方法:不同编译器(C vs C++)的名字改编为了实现重载,C++编译器会对函数名进行名字改编,这个规则是一定的。
如果再由C程序去调用,会找不到函数。
而如果采用同样的C++编译器,因为他知道转换后的名字会是什么,所以能找到。
但是不同的C++编译器可能会因为改编规则不同而无法访问。
因此,有时候希望名字不变。
代码:使用dump观察函数名:如果不加“extern “C””,结果会是:Note:a)Extern “C”不适合类的成员函数b)调用约定发生改变,函数名也会变化。
例如下面的实现,_stdcall导致编译约定被设置为pascal的编译方式,名字会改变:使用dumpbin观察的结果:(下划线+函数名+@+参数字节数(这里两个int为8字节))DLL动态链接库库函数的导出动态链接库中的函数可以分为导出函数和内部函数。
动态链接库中的函数主要有以下几种:(1)在源程序中使用关键字:_declspec(dllexport).此函数可从一个DLL中输出数据,函数,类,类成员函数而不需要DEF文件.原理:根据一个指定的存储类属性(extended-attribute)存储某个项数据.其属性主要有:allocate(“segname”),dllimport,dllexport,naked等,语法如下:_declspec(extended_attribute) declarator;具体使用有二种情况:i._declspec(dllexport) void_cdecl Function1(void);ii.Class _declspec(dllexport) CExportCLass:public Cobject {……..}(2)在DEF文件中通过EXPORTS来声明函数DEF是由一个或多个描述DLL属性的语句组成的文本文件,主要有:LIBRARY语句:用于指定DLL的内部名;DESCRIPTION语句:用于描述DLL特性;SECTIONS 语句:用于设置段的属性,这些属性有:READ ,WRITE ,EXECUTE ,SHARED ;EXPORTS 语句:用于列出被导出的函数名及相关信息;VERSION 语句:该DLL 的版本号。
例:模块定义文件的特点a) 改变编译环境(例如对函数名加“_stdcall ”),名字不便,仍然是def 文件中定义 从DLL 中导出数据变量(1) 使用DEF 文件,设置关键字CONSTANT 导出.通过用CONSTANT 标志时,表明前面导出的不是函数,而是一个数据变量.(2) 可以在应用程序中使用关键字 _declspec(dllimport)引入对DLL 导出的变量的作用,在DLL 源程序中以_declspec(dllexport)来说明要导出的变量.用VC++开发环境生成DLL用VC++生成WIN32 DLL1.Win 32的DLL自动生成过程:FILE->NEW->PROJECT->Win32 Dynamic-Link Library->ok,然后选择相应的类型工程.2.DLL工程类型:●空DLL工程:在需要时编写程序源文件,和DEF文件●简单的DLL工程:只有DllMain(),没有导出和其它变量或函数,不生成DEF文件,编译后也不产生LIB文件.●导出变量,函数和类的DLL:较为详细地建立了DLL中的一些基本成分,包括导出关键字_declspec(dllexport),生成LIB文件.用VC++的MFC生成的DLL1.MFC类库的DLL自动生成过程:FILE->NEW->PROJECT->MFC AppWizard(dll) -> ok,然后选择相应的类型工程。
2.MFC AppWizard DLL类型●静态链接MFC的Regular DLL在内部使用MFC的DLL库,可被MFC和非MFC的应用程序使用,若在工程建立时使用的是MFC静态库,导出函数使用标准C语言接口,创建时自动生成DEF文件,如导出函数:MyExportFunction()用:extern “c” EXPORT MyExportFunction();●动态链接MFC的Regular DLL动态链接MFC 的Regular DLL和静态链接MFC 的Regular DLL基本相似,最后都是由CWinApp派生类的成员函数InitInstance和ExitInstance来完成DLL的初始化和应用程序调用结束时的终止,清理工作.不同的是:DLL在建立时用的是MFC的动态共享库.其导出函数的开头部分使用AFX_MANAGE_STATE宏.●动态链接MFC的扩展DLLMFC 的扩展(Extension) DLL是从已有的MFC类派生新类的DLL,它建立时作用MFC 动态链接库,它的导出函数只能由使用MFC动态共享库的MFC应用程序调用。