《VC调用DLL1.doc》由会员分享,可在线阅读,更多相关《VC调用DLL1.doc(8页珍藏版)》请在三一办公上搜索。
1、在VC中调用DLL文件动态链接库DLL的链接应用程序使用DLL可以采用两种方式:一种是隐式链接,另一种是显式链接。在使用DLL之前首先要知道DLL中函数的结构信息。Visual C+6.0在VCbin目录下提供了一个名为Dumpbin.exe的小程序,用它可以查看DLL文件中的函数结构(在VC安装目录下有一个批处理以设置VC的环境,你可以先运行它, 名字为:vcvars32.bat。 运行后,就可以使用dumpbin了。vc里面自带的dumpbin.exe就非常好用啊,如果你培植了环境变量,或者你也可以在bin/目录下找到他.直接打开cmd.exe,然后输入dumpbin -exports c
2、:windowssystem32kernel32.dll c:kernel32.txt,然后直接到c:kernel32.txt查看其导出 函数.当然dumpbin.exe还有一些其他功能比较好用,你可以看看其命令帮助. 这个Dumpbin是不错, 然而它只能得到导出函数名,对于函数参数的意义却无能为力VC6.0中的Depends工具,和这个功能类似,也是查看DLL输出函数的。可视化方式,更方便。)。 另外,Windows系统将遵循下面的搜索顺序来定位DLL: 1包含EXE文件的目录,2进程的当前工作目录, 3Windows系统目录, 4Windows目录,5列在Path环境变量中的一系列目录。
3、1隐式链接隐式链接就是在程序开始执行时就将DLL文件加载到应用程序当中。实现隐式链接很容易,只要将导入函数关键字_declspec(dllimport)函数名等写到应用程序相应的头文件中就可以了。下面的例子通过隐式链接调用MyDll.dll库中的Min函数。首先生成一个项目为TestDll,在DllTest.h、DllTest.cpp文件中分别输入如下代码:/Dlltest.h#pragma comment(lib,MyDll.lib)extern C_declspec(dllimport) int Max(int a,int b);extern C_declspec(dllimport) i
4、nt Min(int a,int b);/TestDll.cpp#include#includeDlltest.hvoid main()int a;a=min(8,10)printf(比较的结果为%dn,a);在创建DllTest.exe文件之前,要先将MyDll.dll和MyDll.lib拷贝到当前工程所在的目录下面,也可以拷贝到windows的System目录下。如果DLL使用的是def文件,要删除TestDll.h文件中关键字extern C。TestDll.h文件中的关键字Progam commit是要Visual C+的编译器在link时,链接到MyDll.lib文件,当然,开发人员
5、也可以不使用#pragma comment(lib,MyDll.lib)语句,而直接在工程的Setting-Link页的Object/Moduls栏填入MyDll.lib既可。2显式链接显式链接是应用程序在执行过程中随时可以加载DLL文件,也可以随时卸载DLL文件,这是隐式链接所无法作到的,所以显式链接具有更好的灵活性,对于解释性语言更为合适。不过实现显式链接要麻烦一些。在应用程序中用LoadLibrary或MFC提供的AfxLoadLibrary显式的将自己所做的动态链接库调进来,动态链接库的文件名即是上述两个函数的参数,此后再用GetProcAddress()获取想要引入的函数。自此,你就
6、可以象使用如同在应用程序自定义的函数一样来调用此引入函数了。在应用程序退出之前,应该用FreeLibrary或MFC提供的AfxFreeLibrary释放动态链接库。下面是通过显式链接调用DLL中的Max函数的例子。#include #includevoid 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(
7、hDLL,Max);A=Max(5,8);Printf(比较的结果为%dn,a);FreeLibrary(hDLL);/卸载MyDll.dll文件; 在上例中使用类型定义关键字typedef,定义指向和DLL中相同的函数原型指针,然后通过LoadLibray()将DLL加载到当前的应用程序中并返回当前DLL文件的句柄,然后通过GetProcAddress()函数获取导入到应用程序中的函数指针,函数调用完毕后,使用FreeLibrary()卸载DLL文件。在编译程序之前,首先要将DLL文件拷贝到工程所在的目录或Windows系统目录下。使用显式链接应用程序编译时不需要使用相应的Lib文件。另外,
8、使用GetProcAddress()函数时,可以利用MAKEINTRESOURCE()函数直接使用DLL中函数出现的顺序号,如将GetProcAddress(hDLL,Min)改为GetProcAddress(hDLL, MAKEINTRESOURCE(2)(函数Min()在DLL中的顺序号是2),这样调用DLL中的函数速度很快,但是要记住函数的使用序号,否则会发生错误。编程时用ad.h,ad.lib,放在项目当前目录里在头文件中加入#include ad.h在Project SettingLinkObject/library modules加入ad.lib执行时将ad.dll跟你的程序放在同
9、一目录VC如何调用DLL文件 分类: C/C+ 生活 2009-01-18 12:19 3597人阅读 评论(0) 收藏 举报 调用DLL,首先需要将DLL文件映像到用户进程的地址空间中,然后才能进行函数调用,这个函数和进程内部一般函数的调用方法相同。Windows提供了两种将DLL映像到进程地址空间的方法:1. 隐式的加载时链接这种方法需要DLL工程经编译产生的LIB文件,此文件中包含了DLL允许应用程序调用的所有函数的列表,当链接器发现应用程序调用了LIB文件列出的某个函数,就会在应用程序的可执行文件的文件映像中加入一些信息,这些信息指出了包含这个函数的DLL文件的名字。当这个应用程序运行
10、时,也就是它的可执行文件被操作系统产生映像文件时,系统会查看这个映像文件中关于DLL的信息,然后将这个DLL文件映像到进程的地址空间。系统通过DLL文件的名称,试图加载这个文件到进程地址空间时,它寻找DLL 文件的路径按照先后顺序如下:程序运行时的目录,即可执行文件所在的目录;当前程序工作目录系统目录:对于Windows95/98来说,可以调用GetSystemDirectory函数来得到,对于WindowsNT/2000来说,指的是32位Windows的系统目录,也可以调用GetSystemDirectory函数来得到,得到的值为SYSTEM32。Windows目录列在PATH环境变量中的所
11、有目录VC中加载DLL的LIB文件的方法有以下三种:LIB文件直接加入到工程文件列表中在VC中打开File View一页,选中工程名,单击鼠标右键,然后选中“Add Files to Project”菜单,在弹出的文件对话框中选中要加入DLL的LIB文件即可。设置工程的 Project Settings来加载DLL的LIB文件打开工程的 Project Settings菜单,选中Link,然后在Object/library modules下的文本框中输入DLL的LIB文件。通过程序代码的方式加入预编译指令#pragma comment (lib,”*.lib”),这种方法优点是可以利用条件预编
12、译指令链接不同版本的LIB文件。因为,在Debug方式下,产生的LIB文件是Debug版本,如Regd.lib;在Release方式下,产生的LIB文件是Release版本,如Regr.lib。当应用程序对DLL的LIB文件加载后,还需要把DLL对应的头文件(*.h)包含到其中,在这个头文件中给出了DLL中定义的函数原型,然后声明。2 显式的运行时链接 ,(我用的是此方法)隐式链接虽然实现较简单,但除了必须的*.dll文件外还需要DLL的*.h文件和*.lib文件,在那些只提供*.dll文件的场合就无法使用,而只能采用显式链接的方式。这种方式通过调用API函数来完成对DLL的加载与卸载,其能更
13、加有效地使用内存,在编写大型应用程序时往往采用此方式。这种方法编程具体实现步骤如下:使用Windows API函数Load Library或者MFC提供的AfxLoadLibrary将DLL模块映像到进程的内存空间,对DLL模块进行动态加载。使用GetProcAddress函数得到要调用DLL中的函数的指针。不用DLL时,用Free Library函数或者AfxFreeLibrary函数从进程的地址空间显式卸载DLL。例:在应用程序中调用dll文件 在应用程序中要首先装入dll后才能调用导出表中的函数,例如用mfc 创建基于对话框的工程test,并在对话框上放置load按钮,先添加装载代码。1
14、.首先在testdlg.cpp的首部添加变量设置代码: /设置全局变量glibsample用于存储dll句柄HINSTANCE glibsample=null; /如果定义成HANDLE类型,则出错/第二个变量showme是指向dll库中showme()函数的指针typedef int(* Showme)(void);Showme showme;2.利用classwizard为load按钮添加装载dll的代码 void ctestdlg:onloadbutton() /要添加的代码如下 if(glibsample!=NULL) AfxMessageBox(the sample.dll has
15、already been load.); return; /装载sample.dll,未加路径,将在三个默认路径中寻找 (1)windows的系统目录:/windows/system;/(2)dos中path所指出的任何目录; /(3)程序所在的目录; glibsample=Loadlibrary(sample.dll); /返回dll中showme()函数的地址 showme=(Showme)GetProcAddress(glibsample,showme);使用VC的dumpbin.exe查看某个DLL中所输出的符号清单在客户获得某个组件接口指针之前,它必须先将相应的DLL装载到其进程空间
16、中,并创建此组件。CreateInstance(类似函数)可以建立一个组件的实例并给客户返回一个IUnknown接口指针。这是DLL中唯一需要客户显式链接的函数。由于组件中客户所需的所有函数都可以通过一个接口指针而访问到,因此需要在DLL中输出CreateInstance函数以便客户可以调用它。同理,我们需要获得某个DLL的输出符号,并进行转储才能进行调用【jink2005个人理解】。在使用Microsoft Visual C+时,可以用dumpbin.exe来得到某个DLL所输出的符号清单。命令如下:1. dumpbin -exports D:Program FilesCyberLinkPo
17、werDirectorPhotoNowhighgui.dlldumpbin -exports D:Program FilesCyberLinkPowerDirectorPhotoNowhighgui.dll上面命令,因路径中间有空格,要用引号括起。同时,此命令在CMD下是不能直接使用的,除非设置了路径。而VS(我的是2008)的Visual Stdio Tool中有Visual Studio 2008 Command Prompt命令行,它将自动加载所需环境,因此命令在此可以直接使用。如下图所示:dumpbin的命令参数附下:usage: DUMPBIN options files optio
18、ns: /ALL /ARCHIVEMEMBERS /CLRHEADER /DEPENDENTS /DIRECTIVES /DISASM:BYTES|NOBYTES /ERRORREPORT:NONE|PROMPT|QUEUE|SEND /EXPORTS /FPO /HEADERS /IMPORTS:filename /LINENUMBERS /LINKERMEMBER:1|2 /LOADCONFIG /OUT:filename /PDATA /PDBPATH:VERBOSE /RANGE:vaMin,vaMax /RAWDATA:NONE|1|2|4|8,# /RELOCATIONS /SEC
19、TION:name /SUMMARY /SYMBOLS /TLS /UNWINDINFO参考文献:1 (美)Dale Rogerson著, 杨秀章译. COM技术内幕微软组件对象模型M. 北京:清华大学出版社, 1998, 12: 66-68.静态链接库LIB和动态链接库DLL的区别1.什么是静态连接库,什么是动态链接库 静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib 中的指令都全部被直接包含在最终生成的 EXE 文件中了。但是若使用 DLL,该 DLL 不必被包含在最终 EXE 文件中,EXE 文件执行时可以“动态”地引用和卸载这个与 EXE 独立的
20、DLL 文件。静态链接库和动态链接库的另外一个区别在于静态链接库中不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态或静态链接 库。静态链接库与静态链接库调用规则总体比较如下。 对于静态链接库(比较简单):首先,静态链接库的使用需要库的开发者提供生成库的.h头文件和.lib文件。生成库的.h头文件中的声明格式如下:extern C 函数返回类型 函数名(参数表);在调用程序的.cpp源代码文件中如下:#include .lib.h#pragma comment(lib,.debuglibTest.lib) /指定与静态库一起链接第二,因为静态链接库是将全部指令都包含入
21、调用程序生成的EXE文件中。因此如果用的是静态链接库,那么也就不存在“导出某个函数提供给用户使用”的情况,要想用就得全要!要不就都别要!:)对于动态链接库:动态链接库的使用需要库的开发者提供生成的.lib文件和.dll文件。或者只提供dll文件。首先我们必须先注意到DLL内的函数分为两种: (1)DLL 导出函数,可供应用程序调用; (2)DLL 内部函数,只能在 DLL 程序使用,应用程序无法调用它们。因此调用程序若想调用DLL中的某个函数就要以某种形式或方式指明它到底想调用哪一个函数。查看DLL工具Depends的使用说明 怎么样打包程序,如何获取所需dll的信息,这就需要使用VC所带的D
22、epends软件,该软件在VC6安装目录下的tools文件夹里面 D:Microsoft Visual StudioCommonTools,直接双击执行,然后打开exe文件即可,它主要有下面几个注意事项:1)所编的软件所需的Dll文件,可以得到相应的Dll路径,版本,属性等.2)窗口分四部分:左上角是Dll信息窗口,显示你程序所需的Dll模块,右边第一个窗口是所选的Dll模块所使用的函数,右边第二个窗口是所选Dll模块的所有的导出函数,下面窗口是所有需要的Dll模块的属性右边两个窗口出现四个标签:序号,提示,函数,入口点*如果利用导出是函数,那么出现函数名,如果导出的是序号,那么函数项就是N/A(无法显示)出现红色提示表示不正常,一般为没有该导出函数4)该工具得到的是你软件中隐式链接的Dll库,也就是用lib关联的Dll模块,无法显示显式链接的Dll模块,也就是用LoadLibrary函数导入的Dll函数。(切记切记!) 无法提供Borland C+ Builder所提供的Dll文件,无法提供vxd软件的调用。