VC++动态链接库(DLL)编程深入浅出(全)

所需积分/C币:50 2014-05-12 12:40:55 728KB PDF
收藏 收藏 2
举报

对动态链接库,我们还需建立如下概念:   (1)DLL 的编制与具体的编程语言及编译器无关   只要遵循约定的 DLL 接口规范和调用方式,用各种语言编写的 DLL 都可以 相互调用。譬如 Windows 提供的系统 DLL(其中包括了 Windows 的 API),在任 何开发环境中都能被调用,不在乎其是 Visual Basic、 Visual C++还是 Delphi。   (2)动态链接库随处可见   我们在 Windows 目录下的 system32 文件夹中会看到 kernel32.dll、user32.dll 和 gdi32.dll,windows 的大多数 API 都包含在这些
/文件:1ib.cpp #include lib. h int add (int x, int y) return+v 编译这个工程就待到了一个.1ib文件,这个文件就是一个函数库,它提供 了add的功能。将头文件和.1ib文件提交给用户后,用户就可以直接使用其中的 add函数了 标准 Turbo c2.0中的C库函数(我们用来的 scanf、 printf、 memcpy、 strcpy 等)就来自这种静态库。 下面来看看怎么使用这个库,在1 inTest工程所在的工作区内new一个1bCa1l 工程。liba11工程仅包含一个main.cp文件,它演示了静态链接库的调用方法 其源代码如下: #include <stdio. h> #include..lib # pragma comment(1ib,"..\ debug、\ latEst.1ib″)/指定与静态库一起 连接 int main (int argc, char* argv[]) printf("2+3=%d",add(2,3)) 静态链接库的调用就是这么简单,或许我们每天都在用,可是我们没有明 白这个概念。代码中# pragma comment(1ib,"..\ debug\ fitTest.1ib")的 意思是指本文件生成的.obj文件应与1 intest.1ib一起连接。 如果不用# pragma comment指定,则可以直接在VC++中设置,如图2,依次 选择 tools、 options、 directories、 library files菜单或选项,填入库文件路」 径。图2中加红圈的部分为我们添加的 LitEs.1ib文件的路径。 Pt军 x DEbug Compatibility I Build Directories workspace Data Viw OD Platform Show directories for: ry files Directories D: Program FilesiMicrosoft Visual studiolVC9BLIB D: Program File s\Microsoft Visual StudioiVC98MFCYLIB D:vCPROJECTliblibTestdebug PConline软件资讯频道 http://pcedu.com.en OK Cancel 图2在VC中设置库文件路径 这个静态链接库的例子至少让我们明白了库函数是怎么回事,它们是哪来 的。我们现在有下列模糊认识了 (1)库不是个怪物,编写库的程序和编写一般的程序区别不大,只是库不 能单独执行; (2)库提供一些可以给别的程序调用的东东,别的程序要调用它必须以某 种方式指明它要调用之 以上从静态链接库分析而得到的对库的懵懂概念可以直接引申到动态链接 库中,动态链接库与静态链接库在编写和调用上的不同体现在库的外部接口定 义及调用方式略有差异 3库的调试与查看 在具体进入各类DL的详细阐述之前,有必要对库文件的调试与查看方法 进行一下介绍,因为从下一节廾始我们将面对大量的例子工程。 由于库文件不能单独执行,因而在按下F5(开始deυug模式执行)或 CTRL+F5(运行)执行时,其弹出如图3所示的对话框,要求用户输入可执行文 件的路径来启动库函数的执行。这个时侯我们输入要调用该库的EXE文件的路径 就可以对库进行调试了,其调试技巧与一般应用工程的调试一样 eatb1eFor心bug乐 ChIuN Please specify the executablerieanline软件资讯频道 OK hatto:/pcedu, com. cn Cancel Executable file name: 图3库的调试与“运行 通常有比上述做法更好的调试途径,那就是将库工程和应用工程(调用库 的工程)放置在同一VC工作区,只对应用工程进行调试,在应用工程调用库中 函数的语句处设置淅点,执行后按下F11,这样就单步进入了库中的函数。第2 节中的 libRes和 libCal1工程就放在了同一工作区,其工程结构如图4所示。 Workspace bTest. 2 project[s E]-EP lib Call files 白 Source files CPP 了 Header files 圖 Resource files 白、 External Dependencies 目ibh 白- I Test files E Source Files H] lib. cpp 白 Header Filesconline软件资訊 自ibh http:/Pceduco 图4把库工程和调用库的工程放入同一工作区进行调试 上述调试方法对静态链接库和动态链接库而言是一致的。所以本文提供下载 的所有源代码中都包含了库工程和调用库的工程,这二者都被包含在一个工作 区内,这是笔者提供这种打包下载的用意所在。 态链接库中的导出接口可以使用 Visual c+的 Depends工具进行查看,让我 们用 Depends打开系统目录中的user32.d1l,看到了吧?红圈内的就是几个版 本的 MessageBox了!原来它真的在这里啊,原来它就在这里啊 国e阻 dea cy Talker:-[r41 x R El+ Edit Yie Window Halp 叫s囹日可 Pconline胬讯 UEkI IiL Hist 图ctm Tairy Feint 加TML NiL Li 距3 axist I Function lEafy point 1 USEe ELL 国4740a01430x09)! engfindwPr离 OxeA 回一YT1 475 ( Ox0l1B)474 (0xD!DA erurindwFracy 146045小D)昌a4sBe 一 国47012)4rtD!Dc目44eex真 E 418 (2D1lE) 417 (20!DD) essareboaExk 030112AEPE 日口C4,ML 47900F)4800IDE)B 0 IL.Led S STILL DLL 46000聊)4790D 目汇【Bax1 aditec具 0x0HIRB8CC 41)4000E)围q的整增 48200E2)481(0E)围匹【eBxi可离 Ox0OTeAELB 4800E3)40a0E2)围 &IsaEeBMTiN命at置 Cx0rICAET3 E[2目34eB级 4自:的自目A中d 围小山 团图 abates subs[sag图 la Var I,s/12:0pB07,2x2|k 0x77D4000051.200.0 日L049:2241,4k Ied+l *86 WiAl2 enso+Y*s 0sc400051.2a12 B.n00s0112:0p1,0,4来 1xin3en14程 0877g40000512000 STILL DIL 09/05/01 12:00p 674,304A Intel * Win32 console Yet 0872F5000051600.0 4r0512:1p4326A x重n3esl里s 0x78000051200.10 USER32. MLL 09/05/01 12: 00p I】386|n| 0x7100051.28000 图5用 Depends查看DL 当然 Depends工具也可以显示DL的层次结构,若用它打开一个可执行文 件则可以看出这个冋执行文件调用了哪些DL。 好,让我们正式进入动态链接库的世界,先来看看最一般的DLL,即非MFC DL(待续.) VC++动态链接库(LL)编程深入浅出(二) 上节给大家介绍了静态链接库与库的调试与查看(动态链接库(DL编程深 入浅出(一)),本节主要介绍非 MFC DLL。 4.非 MFC DLL 41一个简单的DL 第2节给岀了以静态链接库方式提供add函数接凵的方法,接下来我们来 看看怎样用动态链接库实现一个同样功能的add函数。 如图6,在VC++中mew一个Win32 Dynamic-Link Library工程 dllTest 单击此处下载本工程附件)。注意不要选择 MFC AppWizard(d11),因为用ⅦFC AppWizard(d1)建立的将是第5、6节要讲述的MFC动态链接库。 Files Projects Workspaces Other Documents I ALXGrid Appwizard Project name: ATL COM Appwizard saCluster Resource Type Wizard cUstom卹 appwizard Location: a Datab ase proje ct A DevStudio Add-in wizard D: VCPROJECT\ib\ NISAPI Extension Wizard f Makefile GMFC ActiveX Controlwizard a MFC App Wizard (dl) f Create new workspace MFC卹 wizard exe C Add to current works pace Utility Project 面win32 Application I Dependency af Win? Console Annliralinn swin32 Dynamic-Link Library 西wn32 Static Library PConline软件资识频道 http:pcedu.com.cn Platforms 硎Win32 OK Cancel 图6建立一个非 MFC DLL 在建立的工程中添加1ib.h及1ib.cpp文件,源代码如下: /*文件名:1ib.h米 #ifndef lib h #define lib h extern C int declspec(dllexport)add(int x, int y) #endif 文件名:1b.Cpp*/ #include lib. h int add(int x, int y) return x+v 与第2节对静态链接库的调用相似,我们也建立一个与DL工程处于同·工作 区的应用工程dlCa11,它调用DL中的函数ad,其源代码如下: #include <stdio. h> #include windows. h> Typedef int(* l pAddFur)(int,int);//宏定义函数指针类型 int main(int argc, char *argv) HINSTANCE hDIl;/DLL句柄 lpAddFun addFun;/函数指针 Dll= LoadLibrary(".\\Debug\\dllTest d11") f(hD11 ! NULL) dde (lpAddFun)GetProcAddress(hDll,add") f (addFun NULL int result= addFun(2, 3) printf( %d", result) FreeLibrary(hDl1) eturn 0. 分析上述代码,d11Tles工程中的lib.cpp文件与第2节静态链接库版本完 全相同,不同在于1ib.h对函数add的声明前面添加了 declspec(d1 Export) 语句。这个语句的含义是声明函数add为DL的导出函数。DL内的函数分为两种: (1)DLL导出函数,可供应用程序调用 (2)DL内部函数,只能在DL程序使用,应用程序无法调用它们 而应用程序对木DL的调用和对第2节静态链接库的调用却有饺大差异, 下面我们来逐一分析。 首先,语句 typedef int(*1 pAduN)(int,int)定义了一个与add函数 接受参数类型和返回值均相同的函数指针类型。随后,在main函数中定义了 I pAduN的实例 addIn 其次,在函数main中定义了一个 DLL HINSTANCE句柄实例hl1,通过 Win32ADi函数 Loadlibrary动态加载了DL模块并将DLL模块句柄赋给了 hDlI 再次,在函数main中通过Win32Api函数 GetProcAddress得到了所加载 DLL模块中函数ad的地址并赋给了 addIn。经由函数指针 add fun进行了对DLL 中add函数的调用; 最后,应用工程使用完DL后,在函数main中通过Win32Api函数 FreeLibrary释放了己经加载的DLL模块。 通过这个简单的例子,我们获知DLL定义和调用的一般概念: (1)DL中需以某种特定的方式声明导出函数(或变量、类); (2)应用工程需以某种特定的方式调用DLL的导出函数(或变量、类) 下面我们来对“特定的方式进行”阐述。 4.2声明导出函数 DL中导出数的声明有两种方式:一种为4.1节例子中给出的在函数声明 中加上 declspec( dllexport),这里不再举例说明;另外一种方式是采用模块 定义(.der)文件声明,,de'文件为链接器提供了有关被链接程序的导出、属性 及其他方面的信息。 下面的代码演示了怎样同.deC文件将函数add声明为DL导出函数(需在 d1 LTest工程中添加lib.def文件): lib.def:导出DLL函数 librarY dlltest EXPORTS add 1 def文件的规则为: (1) LIBRARY语句说明.def文件相应的DL; (2) EXPORTS语句后列出要导出数的名称。可以在.def文件中的导出函数 名后加@n,表示要导出函数的序号为n(在进行函数调用时,这个序号将发挥 其作用); (3).def文件中的注释由每个注释行开始处的分号(;)指定,且注释不能 与语句共享一行。 由此可以看出,例子中1ib.def文件的含义为生成名为“d1lest”的动态 链接库,导出其中的ad函数,并指定add函数的序号为1 4.3DLL的调用方式 在4.1节的例子中我们看到了由“ Loadlibrary- GetProcaddress FreeLibrary”系统Api提供的三位一体“DL加载DL函数地址获取-DLL释 放”方式,这种调用方式称为DLL的动态调用。 动态调用方式的特点是完全由编程者用API函数加载和卸载DLL,程序员 可以决定DLL文件何时加载或不加载,显式链接在运行时决定加载哪个DLL 文件 与动态调用方式相对应的就是静态调用方式,“有动必有静”,这来源于 物质世界的对立统。“动与静”,其对立与统·竞无数次在技术领域里得到验 证,譬如静态IP与DCP、静态路由与动态路由等。从前文我们口绎知道,库也分 为静态库与动态库DL,而想不到,深入到DL内部,其调用方式也分为静态与 动态。“动与静”,无处不在。《周易》认识到有动必有静的动静平衡观,《易. 系辞》曰:“动静有常,刚柔断矣”。哲学意味着一种普遍的真理,因此,我们

...展开详情
试读 53P VC++动态链接库(DLL)编程深入浅出(全)
立即下载 低至0.43元/次 身份认证VIP会员低至7折
    一个资源只可评论一次,评论内容不能少于5个字
    小图沫沫 资源一般啊,和大部分书上的一样。
    2014-12-26
    回复
    关注 私信 TA的资源
    上传资源赚积分,得勋章
    最新推荐
    VC++动态链接库(DLL)编程深入浅出(全) 50积分/C币 立即下载
    1/53
    VC++动态链接库(DLL)编程深入浅出(全)第1页
    VC++动态链接库(DLL)编程深入浅出(全)第2页
    VC++动态链接库(DLL)编程深入浅出(全)第3页
    VC++动态链接库(DLL)编程深入浅出(全)第4页
    VC++动态链接库(DLL)编程深入浅出(全)第5页
    VC++动态链接库(DLL)编程深入浅出(全)第6页
    VC++动态链接库(DLL)编程深入浅出(全)第7页
    VC++动态链接库(DLL)编程深入浅出(全)第8页
    VC++动态链接库(DLL)编程深入浅出(全)第9页
    VC++动态链接库(DLL)编程深入浅出(全)第10页
    VC++动态链接库(DLL)编程深入浅出(全)第11页
    VC++动态链接库(DLL)编程深入浅出(全)第12页
    VC++动态链接库(DLL)编程深入浅出(全)第13页
    VC++动态链接库(DLL)编程深入浅出(全)第14页
    VC++动态链接库(DLL)编程深入浅出(全)第15页
    VC++动态链接库(DLL)编程深入浅出(全)第16页

    试读已结束,剩余37页未读...

    50积分/C币 立即下载 >