ImageVerifierCode 换一换
格式:DOC , 页数:10 ,大小:54KB ,
资源ID:3100184      下载积分:20 文钱
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,省得不是一点点
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.wenke99.com/d-3100184.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: QQ登录   微博登录 

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(如何用VC++创建及调用DLL.doc)为本站会员(hw****26)主动上传,文客久久仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知文客久久(发送邮件至hr@wenke99.com或直接QQ联系客服),我们立即给予删除!

如何用VC++创建及调用DLL.doc

1、【转】如何用 VC+创建及调用 DLL(2010-12-01 13:57:33) 一、前言自从微软推出 16 位的 Windows 操作系统起,此后每种版本的 Windows 操作系统都非常依赖于动态链接库(DLL)中的函数和数据,实际上 Windows 操作系统中几乎所有的内容都由 DLL以一种或另外一种形式代表着,例如显示的字体和图标存储在 GDI DLL 中、显示 Windows桌面和处理用户的输入所需要的代码被存储在一个 User DLL 中、Windows 编程所需要的大量的 API 函数也被包含在 Kernel DLL 中。在 Windows 操作系统中使用 DLL 有很多优点,最

2、主要的一点是多个应用程序、甚至是不同语言编写的应用程序可以共享一个 DLL 文件,真正实现了资源“共享“,大大缩小了应用程序的执行代码,更加有效的利用了内存;使用 DLL 的另一个优点是 DLL 文件作为一个单独的程序模块,封装性、独立性好,在软件需要升级的时候,开发人员只需要修改相应的DLL 文件就可以了,而且,当 DLL 中的函数改变后,只要不是参数的改变,程序代码并不需要重新编译。这在编程时十分有用,大大提高了软件开发和维护的效率。既然 DLL 那么重要,所以搞清楚什么是 DLL、如何在 Windows 操作系统中开发使用 DLL 是程序开发人员不得不解决的一个问题。本文针对这些问题,通

3、过一个简单的例子,即在一个 DLL 中实现比较最大、最小整数这两个简单函数,全面地解析了在 Visual C+编译环境下编程实现 DLL 的过程,文章中所用到的程序代码在 Windows98 系统、Visual C+6.0 编译环境下通过。二、DLL 的概念DLL 是建立在客户/服务器通信的概念上,包含若干函数、类或资源的库文件,函数和数据被存储在一个 DLL(服务器)上并由一个或多个客户导出而使用,这些客户可以是应用程序或者是其它的 DLL。DLL 库不同于静态库,在静态库情况下,函数和数据被编译进一个二进制文件(通常扩展名为*.LIB),Visual C+的编译器在处理程序代码时将从静态库

4、中恢复这些函数和数据并把他们和应用程序中的其他模块组合在一起生成可执行文件。这个过程称为“静态链接“,此时因为应用程序所需的全部内容都是从库中复制了出来,所以静态库本身并不需要与可执行文件一起发行。在动态库的情况下,有两个文件,一个是引入库(.LIB)文件,一个是 DLL 文件,引入库文件包含被 DLL 导出的函数的名称和位置,DLL 包含实际的函数和数据,应用程序使用 LIB 文件链接到所需要使用的 DLL 文件,库中的函数和数据并不复制到可执行文件中,因此在应用程序的可执行文件中,存放的不是被调用的函数代码,而是 DLL 中所要调用的函数的内存地址,这样当一个或多个应用程序运行是再把程序代

5、码和被调用的函数代码链接起来,从而节省了内存资源。从上面的说明可以看出,DLL 和.LIB 文件必须随应用程序一起发行,否则应用程序将会产生错误。微软的 Visual C+支持三种 DLL,它们分别是:Non-MFC Dll(非 MFC 动态库)Regular Dll(常规 DLL)Extension Dll(扩展 DLL)。Non-MFC DLL:指的是不用 MFC 的类库结构,直接用 C 语言写的 DLL,其导出的函数是标准的 C 接口,能被非 MFC 或 MFC 编写的应用程序所调用。Regular DLL:和下述的 Extension Dlls 一样,是用 MFC 类库编写的,它的一个

6、明显的特点是在源文件里有一个继承 CWinApp 的类(注意:此类 DLL 虽然从 CWinApp 派生,但没有消息循环),被导出的函数是 C 函数、C+类或者 C+成员函数(注意不要把术语 C+类与 MFC的微软基础 C+类相混淆),调用常规 DLL 的应用程序不必是 MFC 应用程序,只要是能调用类 C 函数的应用程序就可以,它们可以是在 Visual C+、Dephi、Visual Basic、Borland C 等编译环境下利用 DLL 开发应用程序。常规 DLL 又可细分成静态链接到 MFC 和动态链接到 MFC 上的,这两种常规 DLL 的区别将在下面介绍。与常规 DLL 相比,使

7、用扩展 DLL 用于导出增强 MFC 基础类的函数或子类,用这种类型的动态链接库,可以用来输出一个从 MFC 所继承下来的类。Extension Dll:扩展 DLL 是使用 MFC 的动态链接版本所创建的,并且它只被用 MFC 类库所编写的应用程序所调用。例如你已经创建了一个从 MFC 的 CtoolBar 类的派生类用于创建一个新的工具栏,为了导出这个类,你必须把它放到一个 MFC 扩展的 DLL 中。扩展 DLL 和常规 DLL 不一样,它没有一个从 CWinApp 继承而来的类的对象,所以,开发人员必须在 DLL中的 DllMain 函数添加初始化代码和结束代码。三、动态链接库的创建在

8、 Visual C+6.0 开发环境下,打开 FileNewProject 选项,可以选择 Win32 Dynamic-Link Library 或 MFC AppWizarddll来以不同的方式来创建 Non-MFC Dll、Regular Dll、Extension Dll 等不同种类的动态链接库。1 Win32 Dynamic-Link Library 方式创建 Non-MFC DLL 动态链接库每一个 DLL 必须有一个入口点,这就象我们用 C 编写的应用程序一样,必须有一个WINMAIN 函数一样。在 Non-MFC DLL 中 DllMain 是一个缺省的入口函数,你不需要编写自己

9、的 DLL 入口函数,用这个缺省的入口函数就能使动态链接库被调用时得到正确的初始化。如果应用程序的 DLL 需要分配额外的内存或资源时,或者说需要对每个进程或线程初始化和清除操作时,需要在相应的 DLL 工程的.CPP 文件中对 DllMain()函数按照下面的格式书写。BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)switch( ul_reason_for_call )case DLL_PROCESS_ATTACH:.case DLL_THREAD_ATTACH:.case DL

10、L_THREAD_DETACH:.case DLL_PROCESS_DETACH:.return TRUE;参数中:hMoudle:是动态库被调用时所传递来的一个指向自己的句柄(实际上,它是指向_DGROUP段的一个选择符);ul_reason_for_call:是一个说明动态库被调原因的标志,当进程或线程装入或卸载动态链接库的时候,操作系统调用入口函数,并说明动态链接库被调用的原因,它所有的可能值为:DLL_PROCESS_ATTACH: 进程被调用DLL_THREAD_ATTACH: 线程被调用DLL_PROCESS_DETACH: 进程被停止DLL_THREAD_DETACH: 线程被停

11、止lpReserved :为保留参数。到此为止,DLL 的入口函数已经写了,剩下部分的实现也不难,你可以在 DLL 工程中加入你所想要输出的函数或变量了。我们已经知道 DLL 是包含若干个函数的库文件,应用程序使用 DLL 中的函数之前,应该先导出这些函数,以便供给应用程序使用。要导出这些函数有两种方法,一是在定义函数时使用导出关键字_declspec(dllexport),另外一种方法是在创建 DLL 文件时使用模块定义文件.Def。需要读者注意的是在使用第一种方法的时候,不能使用 DEF 文件。下面通过两个例子来说明如何使用这两种方法创建 DLL 文件。1)使用导出函数关键字_declsp

12、ec(dllexport)创建 MyDll.dll,该动态链接库中有两个函数,分别用来实现得到两个数的最大和最小数。在 MyDll.h 和 MyDLL.cpp 文件中分别输入如下原代码:/MyDLL.hextern “C“ _declspec(dllexport) int Max(int a, int b);extern “C“ _declspec(dllexport) int Min(int a, int b);/MyDll.cppincludeinclude“MyDll.h“int Max(int a, int b)if(a=b)return a;elsereturn b;int Min(

13、int a, int b)if(a=b)return b;elsereturn a;该动态链接库编译成功后,打开 MyDll 工程中的 debug 目录,可以看到MyDll.dll、MyDll.lib 两个文件。LIB 文件中包含 DLL 文件名和 DLL 文件中的函数名等,该 LIB 文件只是对应该 DLL 文件的“映像文件“,与 DLL 文件中,LIB 文件的长度要小的多,在进行隐式链接 DLL 时要用到它。读者可能已经注意到在 MyDll.h 中有关键字“extern C“,它可以使其他编程语言访问你编写的 DLL 中的函数。2)用.def 文件创建工程 MyDll为了用.def 文件创

14、建 DLL,请先删除上个例子创建的工程中的 MyDll.h 文件,保留MyDll.cpp 并在该文件头删除include MyDll.h 语句,同时往该工程中加入一个文本文件,命名为 MyDll.def。一个.def 文件中只有两个必需的部分:LIBRARY 和 EXPORTS。在该文件中加入如下代码:LIBRARY MyDllEXPORTSMaxMin其中 LIBRARY 语句说明该 def 文件是属于相应 DLL 的(在这里是指属于 MyDLL.DLL 的),EXPORTS 语句下列出要导出的函数名称。我们可以在.def 文件中的导出函数后加 n,如Max1,Min2,表示要导出的函数顺序

15、号,在进行显式连时可以用到它。该 DLL 编译成功后,打开工程中的 Debug 目录,同样也会看到 MyDll.dll 和 MyDll.lib 文件。注:_declspec(dllexport)和.def 文件这两种方式不能同时使用。2MFC AppWizarddll方式生成常规/扩展 DLL在 MFC AppWizarddll下生成 DLL 文件又有三种方式,在创建 DLL 时,要根据实际情况选择创建 DLL 的方式。一种是常规 DLL 静态链接到 MFC,另一种是常规 DLL 动态链接到MFC。两者的区别是:前者使用的是 MFC 的静态链接库,生成的 DLL 文件长度大,一般不使用这种方式

16、,后者使用 MFC 的动态链接库,生成的 DLL 文件长度小;动态链接到 MFC 的规则 DLL 所有输出的函数应该以如下语句开始:AFX_MANAGE_STATE(AfxGetStaticModuleState( ) /此语句用来正确地切换 MFC 模块状态最后一种是 MFC 扩展 DLL,这种 DLL 特点是用来建立 MFC 的派生类,Dll 只被用 MFC 类库所编写的应用程序所调用。前面我们已经介绍过,Extension DLLs 和 Regular DLLs 不一样,它没有一个从 CWinApp 继承而来的类的对象,编译器默认了一个 DLL 入口函数DLLMain()作为对 DLL

17、的初始化,你可以在此函数中实现初始化,代码如下:BOOL WINAPI APIENTRY DLLMain(HINSTANCE hinstDll,DWORD reason ,LPVOID flmpload)switch(reason)/初始化代码;return true;参数 hinstDll 存放 DLL 的句柄,参数 reason 指明调用函数的原因,lpReserved 是一个被系统所保留的参数。对于隐式链接是一个非零值,对于显式链接值是零。在 MFC 下建立 DLL 文件,会自动生成 def 文件框架,其它与建立传统的 Non-MFC DLL没有什么区别,只要在相应的头文件写入关键字_d

18、eclspec(dllexport)函数类型和函数名等,或在生成的 def 文件中 EXPORTS 下输入函数名就可以了。需要注意的是在向其它开发人员分发 MFC 扩展 DLL 时,不要忘记提供描述 DLL 中类的头文件以及相应的.LIB 文件和DLL 本身,此后开发人员就能充分利用你开发的扩展 DLL 了。四、动态链接库 DLL 的链接应用程序使用 DLL 可以采用两种方式:一种是隐式链接,另一种是显式链接。在使用DLL 之前首先要知道 DLL 中函数的结构信息。Visual C+6.0 在 VC in 目录下提供了一个名为 Dumpbin.exe 的小程序,用它可以查看 DLL 文件中的函

19、数结构。另外,Windows 系统将遵循下面的搜索顺序来定位 DLL: 1包含 EXE 文件的目录,2进程的当前工作目录, 3Windows 系统目录, 4Windows 目录,5列在 Path 环境变量中的一系列目录。1隐式链接隐式链接就是在程序开始执行时就将 DLL 文件加载到应用程序当中。实现隐式链接很容易,只要将导入函数关键字_declspec(dllimport)函数名等写到应用程序相应的头文件中就可以了。下面的例子通过隐式链接调用 MyDll.dll 库中的 Min 函数。首先生成一个项目为TestDll,在 DllTest.h、 DllTest.cpp 文件中分别输入如下代码:/

20、Dlltest.h#pragma comment(lib,“MyDll.lib“)extern “C“_declspec(dllimport) int Max(int a,int b);extern “C“_declspec(dllimport) int Min(int a,int b);/TestDll.cppi ncludei nclude“Dlltest.h“void main()int a;a=min(8,10)printf(“比较的结果为%d “,a);在创建 CallDllDemo.exe 文件之前,要先将 MFCDllDemo.dll 和 MFCDllDemo.lib 拷贝到当前

21、工程所在的目录下面,也可以拷贝到 windows 的 System 目录下。如果 DLL 使用的是 def文件,要删除 TestDll.h 文件中关键字 extern “C“。TestDll.h 文件中的关键字 Progam commit 是要 Visual C+的编译器在 link 时,链接到 MyDll.lib 文件,当然,开发人员也可以不使用#pragma comment(lib,“MyDll.lib“)语句,而直接在工程的 Setting-Link 页的Object/Moduls 栏填入 MyDll.lib 既可。2显式链接显式链接是应用程序在执行过程中随时可以加载 DLL 文件,也可

22、以随时卸载 DLL 文件,这是隐式链接所无法作到的,所以显式链接具有更好的灵活性,对于解释性语言更为合适。不过实现显式链接要麻烦一些。在应用程序中用 LoadLibrary 或 MFC 提供的AfxLoadLibrary 显式的将自己所做的动态链接库调进来,动态链接库的文件名即是上述两个函数的参数,此后再用 GetProcAddress()获取想要引入的函数。自此,你就可以象使用如同在应用程序自定义的函数一样来调用此引入函数了。在应用程序退出之前,应该用FreeLibrary 或 MFC 提供的 AfxFreeLibrary 释放动态链接库。下面是通过显式链接调用DLL 中的 Max 函数的例

23、子。includeincludevoid main(void)typedef int (*pMax)(int a,int b);typedef int (*pMin)(int a,int b);HINSTANCE hDLL;PMax MaxhDLL=LoadLibrary(“MyDll.dll“);/加载动态链接库 MyDll.dll 文件;Max=(pMax)GetProcAddress(hDLL,“Max“);a=Max(5,8);Printf(“比较的结果为%d “,a);FreeLibrary(hDLL);/卸载 MyDll.dll 文件;在上例中使用类型定义关键字 typedef,定

24、义指向和 DLL 中相同的函数原型指针,然后通过 LoadLibray()将 DLL 加载到当前的应用程序中并返回当前 DLL 文件的句柄,然后通过GetProcAddress()函数获取导入到应用程序中的函数指针,函数调用完毕后,使用 FreeLibrary()卸载 DLL 文件。在编译程序之前,首先要将 DLL 文件拷贝到工程所在的目录或 Windows 系统目录下。使用显式链接应用程序编译时不需要使用相应的 Lib 文件。另外,使用 GetProcAddress()函数时,可以利用 MAKEINTRESOURCE()函数直接使用 DLL 中函数出现的顺序号,如将GetProcAddress(hDLL,“Min“)改为 GetProcAddress(hDLL, MAKEINTRESOURCE(2)(函数Min()在 DLL 中的顺序号是 2),这样调用 DLL 中的函数速度很快,但是要记住函数的使用序号,否则会发生错误。本文通过通俗易懂的方式,全面介绍了动态链接库的概念、动态链接库的创建和动态链接库的链接,并给出个简单明了的例子,相信读者看了本文后,能够创建自己的动态链接库并应用到后续的软件开发当中去了,当然,读者要熟练操作 DLL,还需要在大量的实践中不断摸索,希望本文能起到抛砖引玉的作用。

Copyright © 2018-2021 Wenke99.com All rights reserved

工信部备案号浙ICP备20026746号-2  

公安局备案号:浙公网安备33038302330469号

本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。