友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
狗狗书籍 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

C语言实例教程(PDF格式)-第140章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!




动态链接库:  



  l 系统预安装的DLL,如KERNEL32。DLL和USER32。DLL等  



  l 当前目录  



  l Windows的系统的目录,如WINNTsystem32  



  l Windows所在的目录,如WINNT  



  l 环境变量PATH中所指定的目录  


…………………………………………………………Page 673……………………………………………………………

                                            



                    图13。2 tester应用程序的运行结果  



如果Windows在上面的目录中未找到所需要的DLL,则弹出如图13。1所 

示的对话框。这里,我们把msgbox。dll文件拷贝到testerDebug 目录 

下,再运行应用程序,则出现如图13。2所示的对话框。  



    (2) 使用显式链接  



如果没有与DLL相关联的LIB文件,则必须使用显式链接。使用显式链 

接同样必须知道函数返回值的类型和所传递的参数个数、类型和顺 

序。与使用隐含链接不同的是,使用显式链接的应用程序在调用DLL 

中的导出函数前,必须使用LoadLibrary()函数加载DLL并得到一个模 

块句柄。然后使用该句柄调用GetProcAddress()函数获得所需调用的 

导出函数的指针,并通过该指针调用DLL中的导出函数,这种模式使 

用显式链接到DLL的应用程序不再需要相应的LIB文件。在使用完毕之 

后,还需调用FreeLibrary()函数释放加载的DLL。  



下面我们使用显式链接的方式来实现前面的例子。  



由于使用指针来调用DLL中的导出函数,所以本例中不再需要 

msgbox。h文件。  



在tester。cpp中添加的代码如下所示:  



#include   



typedef int (CALLBACK* DLLFUNC)(  



LPCTSTR lpText=〃虽然这个例子有一些简单,但它工作得非常的好 !〃;  



LPCTSTR lpCaption=〃一个简单的例子〃;  



UINT=MB_OK);  



int WINAPI WinMain(HINSTANCE hInstance;  



HINSTANCE hPrevInstance;  



LPSTR lpCmdLine;  



int nCmdShow)  



{  


…………………………………………………………Page 674……………………………………………………………

HINSTANCE hDLL;  



DLLFUNC MsgBox;  



hDLL = LoadLibrary(〃msgbox〃);  



if (hDLL != NULL)  



{  



MsgBox =   



(DLLFUNC)GetProcAddress(hDLL;〃MsgBox〃);  



return MsgBox();  



}  



}  



LoadLibrary()函数的参数是所调用的DLL的名字,这个名字不是放入 

输入库文件中的名字,而是DLL的文件名。如果文件的扩展名 

为。DLL,则可以省略。  



这个程序的运行结果同使用隐含链接的前一个程序一样,但它的内部 

实现是很不相同的。使用显式链接的应用程序加载时,所调用的DLL 

并不加载,只有当应用程序调用LoadLibray()时系统才加载相应的 

DLL,并在应用程序调用FreeLibrary()时卸载该DLL。使用隐含链接 

的应用程序调用DLL中的导出函数时,方法同调用一般的函数一样, 

而使用显式链接的应用程序必须使用指针来调用。由于使用了指针, 

因此在编译时不能验证参数的合法性,通过指针使用不合法的参数来 

调用DLL中的导出函数将会导致不可预料的后果。  



很明显,使用隐含链接的方式调用DLL中的导出函数要比使用显式链 

接方便得多。但在某些情况下我们必须使用显式链接。事实上,使用 

显式链接调用DLL提供了更大的灵活性。尤其在没有与DLL相对应的 

LIB文件时,我们只能使用显式链接来调用DLL中的导出函数,并且, 

只要我们使用函数名作参数来调用GetProcAddress(),在更新DLL 

时,就没有必要重新链接应用程序。另外,使用隐含链接的方式的应 

用程序加载DLL时如果发生错误 (如DLL文件未找到或是DLL中的 

DllMain()函数初始化失败)时,应用程序将被终止,而使用显式链 

接的应用程序则可以使用如上面的例子中所给出的方法来避免出现这 

种情况 (可以使用所创建的两个不同版本的tester程序来验证这一 

点)。  


…………………………………………………………Page 675……………………………………………………………

由于应用程序调用LoadLibrary()函数时才加载DLL,因此使用显式链 

接的应用程序的加载速度要比使用隐含链接的应用程序快。使用显式 

链接的另一个好处是,应用程序可以在运行时决定所加载的DLL。  



但是要记住,由于使用了指针来传递应用程序的参数,因此编译器在 

编译时无法确认应用程序所传递的参数类型是否合法。传递不合法的 

参数给DLL中的导出函数的一件危险的事。在程序调试的过程中我们 

一定需要注意这一点。  



          第三节 使用动态链接连库扩展MFC  



我们还可以使用DLL来实现从MFC派生的一些可重用类,这种动态链接 

库一般称作MFC扩展动态链接库 (MFC Extension DLL)。正如这个名称 

所暗示的那样,通过这种方式我们可以扩展MFC所包括的内容,使得 

使用MFC编程更加的方便。此外,如果需要在应用程序和DLL之间传递 

MFC或者由MFC派生的对象的指针的话,我们也必须使用MFC扩展DLL。  



在本节中,我们使用MFC扩展DLL来创建一个输入通用对话框,如图 

13。3所示。该对话框很象Visual  Basic中的InputBox函数所产生的对 

话框,使用过Visual  Basic的程序员都有印象,函数InputBox非常之 

好用,这里,我们来使用动态链接库在Visual   C++ 的MFC中也创建这 

么一个好用的类。  



                               



                 图13。 3 输入通用对话框  



输入通用对话框由类CInputDlg封装,类CInputDlg提供了一个公有成 

员函数GetInput,该成员函数的原型如下:  



CString GetInput(CString Title; CString Prompt)  



第一个参数Title表示输入对话框的标题,在图13。3中为 “输入”; 

第二个参数Prompt代表在输入对话框中显示的简短提示文本,在图 

13。3中为 “请输入对话框的标题:”。函数的返回值为用户在对话框 

的文本框中输入的字符串。如果用户没有输入任何字符串或者单击了 

 “取消”按钮,返回值为空串〃〃。  



下面我们来介绍该对话框的创建和使用。首先讲述DLL工程 

ExtDllDemo的创建。该工程实现了类CInputDlg的导出。  


…………………………………………………………Page 676……………………………………………………………

1。             使用AppWizard创建一个MFC扩展DLL工程,将工程取名为 

ExtDllDemo。  



2。  向工程中添加一个对话框资源IDD_INPUT,按图13。3绘制对话框中 

的各控件。这些控件的资源ID如表所示。  



                   表13。 1 对话框资源IDD_INPUT中的控件属性  



                           控件          资源ID  



                           提示文本        IDC_PROMPT  

                           标签  



                           输入文本        IDC_EDIT  

                           框  



3。         使用ClassWizard为对话框资源IDD_INPUT创建新的对话框类 

CInputDlg,该类直接派生于CDialog。按下面的代码修改类 

CInputDlg的头文件和实现文件。  



#if !defined(AFX_INPUTDLG_H__02DB98CF_1F76_11D2_971A_0000B4810A31__INCLUDED_)  



#define AFX_INPUTDLG_H__02DB98CF_1F76_11D2_971A_0000B4810A31__INCLUDED_  



#if _MSC_VER 》= 1000  



#pragma once  



#endif // _MSC_VER 》= 1000  



// InputDlg。h : 头文件  



//  



// 以下对话框 ID 常量需要手动添加  



#define IDC_EDIT 1000  



#define IDC_PROMPT 1001  



#defin
返回目录 上一页 下一页 回到顶部 0 0
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!