dll文件详解.docx_第1页
dll文件详解.docx_第2页
dll文件详解.docx_第3页
dll文件详解.docx_第4页
dll文件详解.docx_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

DLL 文件详解Part1 dll文件与exe文件的区别:动态链接库(Dynamic Link Library,缩写为DLL)是一个可以被其它应用程序共享的程序模块,其中封装了一些可以被共享的例程和资源。动态链接库文件的扩展名一般是dll,也有可能是drv、sys和fon,它和可执行文件(exe)非常类似.具体说:DLL中虽然包含了可执行代码却不能单独执行,而应由Windows应用程序直接或间接调用。动态链接是相对于静态链接而言的。所谓静态链接是指把要调用的函数或者过程链接到可执行文件中,成为可执行文件的一部分。换句话说,函数和过程的代码就在程序的exe文件中,该文件包含了运行时所需的全部代码。当多个程序都调用相同函数时,内存中就会存在这个函数的多个拷贝,这样就浪费了宝贵的内存资源。而动态链接所调用的函数代码并没有被拷贝到应用程序的可执行文件中去,而是仅仅在其中加入了所调用函数的描述信息(往往是一些重定位信息)。仅当应用程序被装入内存开始运行时,在Windows的管理下,才在应用程序与相应的DLL之间建立链接关系。当要执行所调用DLL中的函数时,根据链接产生的重定位信息,Windows才转去执行DLL中相应的函数代码。共有三种动态链接库的形式:Win32DLL,MFC常规DLL和MFC拓展DLL1、Win32DLL使用的是Win32的API实现的,只能导出函数,能被各种应用程序调用,适用范围最广。WIN32 DLL 是纯C+ API 写的,体积也比较小。一般做MFC程序时,选用MFC DLL,MFC常规DLL没有显性DLLMAIN。MFC DLL 使用了MFC 体积比较大,MFC DLL本身也分为两种,一种是常规DLL,一种是扩展DLL。2.MFC常规DLL是适用MFC创建的,就像MFC程序跟Win32程序的关系一样,MFC常规DLL和Win32DLL的关系也是如此。它使用MFC的机制,只能导出标准C函数。如此,它便可以被大部分Win32程序调用。3.MFC拓展DLL也也使用的是MFC机制创建的,相比于MFC常规DLL,拓展DLL可以导出C+类和MFC派生类,如此扩大了DLL的接口范围。此长 彼消,MFC拓展DLL的适用范围较小,只能被MFC程序调用。因为它导出的不只是函数,还有C+类和MFC派生类。三者区别展开来说:MFC DLL 和win32 DLL的差别就是一个使用MFC类库,一个不使用,如果你代码中用到的MFC,那么一定要创建MFC DLL,因为win32 DLL用不了MFC类。MFC常规DLL在DLL内部可以用MFC类的,但是给外部的接口并不提供MFC类的支持,还是提供Win32 DLL同样的接口,与Win32的差别在于,它的内部可以用MFC类。扩展DLL可以有C+的接口,它可以导出C+类给客户端。导出的函数可以使用C+/MFC数据类型做参数或返回值,导出一个类时客户端能创建类对象或者派生这个类。同时,在DLL中也可以使用MFC。MFC扩展DLL是通常实现从现有Microsoft基础类库类派生的可重用类的DLL。 MFC扩展DLL具有下列功能和要求: 1 客户端可执行文件必须是用定义的_AFXDLL编译的MFC应用程序。 2 扩展DLL也可由动态链接到MFC的规则DLL使用。 3 扩展DLL应该用定义的_AFXEXT编译。这将强制同时定义_AFXDLL,并确保从MFC头文件中拉入正确的声明。它也确保了在生成DLL时将AFX_EXT_CLASS定义为_declspec(dllexport),这在使用此宏声明扩展DLL中的类时是必要的。 4 扩展DLL不应实例化从CWinApp派生的类,而应依赖客户端应用程序(或DLL)提供此对象。 5 但扩展DLL应提供DllMain函数,并在那里执行任何必需的初始化。 扩展DLL是使用MFC动态链接库版本(也称作共享MFC版本)生成的。只有用共享MFC版本生成的MFC可执行文件 (应用程序或规则DLL)才能使用扩展DLL。客户端应用程序和扩展DLL必须使用相同版本的MFCx0.dll。使用扩展DLL,可以从MFC派生新的自定义类,然后将此“扩展”版本的MFC提供给调用DLL的应用程序。具体执行时,主要是资源的管理:mfc扩展dll会把当前dll的句柄加入一个全局资源句柄列表。而普通的dll则不会。即使支持mfc也不会,这样你每次用mfc类创建资源的时候要多写几行代码 。但你用在mfc扩展dll用win32来访问资源也需要多写代码。=扩展DLL 可以导出类扩展DLL服务器方的类定义: class AFX_CLASS_EXPORT 到出类名: public 基类名 . 扩展DLL客户方的类声明头文件: #pragma comment(lib,lib文件名) class AFX_CLASS_IMPORT 到出类名: public 基类名 . =常规DLL 可以导出标准C语言函数常规DLL服务器方的函数定义: /头文件中函数声明 extern C _declspec(dllexport) 返回值 函数名(形式参数声明) ; /源文件中函数实现 extern C _declspec(dllexport) 返回值 函数名(形式参数声明) AFX_MANAGE_STATE ( AfxGetStaticModuleState() );/第一条语句 . /在def模块文件中声明函数序号 EXPORTS 导出函数名 序号数字 常规DLL客户方的隐式函数声明头文件:=另外,所有的动态链接库都有两种链接方式:隐式调用和显示调用。隐式调用编译程序时需要头文件、lib文件,运行时需要DLL文件,并且运行过程中DLL文件一直被占用。显式调用编译时什么都不需要,在需要使用DLL中的函数时,通过LoadLibrary()和FindProcAdress()这两个API调用。只需要一个DLL文件即可,而且在需要使用的时候DLL才被占用,使用完毕即被解除占用。DLL中有哪些函数可以通过Depends工具查询。=Part2如何制作生成dll文件?一.Win32动态链接库1.制作的步骤:(1)新建WIN32 Dynamic-link Library工程,工程名为MyDll,选择A simple DLL project类型。(2)MyDll.h的内容如下:以下是引用片段:extern C _declspec(dllexport) int sum(int a,int b);/本文所有的例子只有一个sum即加法函数。(3)MyDll.cpp的内容如下:以下是引用片段:#include stdafx.h#include windows.h#include MyDll.hBOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)return TRUE;extern C _declspec(dllexport)int sum(int a, int b)return a+b;(4)编译之后产生了MyDll.lib与MyDll.dll两个文件。2.使用方法:(1).隐式调用法: 将MyDll.lib和MyDll.h拷贝到需要应用该DLL的工程的目录下,将MyDll.dll拷贝到产生的应用程序的目录下,并在需要应用该DLL中的函数的CPP文件中添加如下几行:以下是引用片段:#include MyDll.h#pragma comment(lib,MyDll);(2).显示调用法:将MyDll.lib和MyDll.h拷贝到需要应用该DLL的工程的目录下,将MyDll.dll拷贝到产生的应用程序的目录下,并在需要应用该DLL中的函数的CPP文件中包含头文件,如:以下是引用片段:#include MyDll.h同时还需要在Project-Setting-Link-Object/library modules的框中增加MyDll.lib这个库。二.MFC动态链接库1.制作的步骤:(1)新建MFC AppWizard(dll)工程,工程名为MFCDll,选择Regular DLL using shared MFC DLL类型。(2)在生成的MFCDll.cpp文件后面增加下面几行:以下是引用片段:int sum(int a, int b)return a+b;(3)在生成的MFCDll.def文件后面增加如下:以下是引用片段:sum 1 ;表示第一个函数是sum(4)编译后会产生两个文件MFCDll.lib,MFCDll.dll2.使用方法(1)隐式调用法: 将MFCDll.lib拷贝到需要应用该DLL的工程的目录下,将MyDll.dll拷贝到产生的应用程序的目录下,并在需要应用该DLL中的函数的CPP文件中添加如下几行:/注意这里没有在MFCDll.h中声明函数,所以不能直接包含MFCDll.h来声明函数。以下是引用片段:#pragma comment(lib,MFCDll);int sum(int a, int b);/当然如果你的DLL中有很多函数,那可以另外写个MFCDll.h,包含所有的函数声明,然后直接将头文件包含进去(2)显示调用法:与Win32的调用方法一样,不需要#pragma comment(lib,MFCDll);,但是需要在Project-Setting-Link-Object/library modules的框中增加MFCDll.lib这个库。=另一个例子:具体在写DLL文件头文件中一般如此: #ifdef DLL_EXPORT #define DECLDIR _declspec(dllexport) #else #define DECLDIR _declspec(dllimport) #endif extern C DECLDIR void alert(); 这样使得在定义了DLL_EXPORT的环境下,头文件中,函数为导出;相反为导入。于是,我们可以使用同一个头文件。此时是在写DLL,还是在使用DLL,只需要通过这个开关来告诉编译器就可以了。实现cpp中一般这么写: #include stdafx.h #define DLL_EXPORT #include MyHead.h extern C DECLDIR void alert() MessageBoxA(NULL, Hello,World!, 0, 0); 在引用头文件前定义DLL_EXPORT,告诉编译器此时这些函数需要导出。隐式调用 #include stdafx.h #include MyHead.h #pragma comment(lib,MyTestDLL.lib) int _tmain(int argc, _TCHAR* argv) alert(); / 直接调用 return 0; 由于我们没有定义DLL_EXPORT,那么头文件中的函数就会被从DLL中导入。显式调用 #include stdafx.h #include typedef void

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论