VC++环境下动态链接库的开发及应用
(5)为了实现应用程序的国际化,往往需要使用动态链接库
1.6. Visual C++支持的动态链接库的类型
Visual C++支持三种DLL,它们分别是Non-MFC DLL(非MFC动态库)、MFC Regular DLL(MFC规则DLL)、MFC Extension DLL(MFC扩展DLL)。
(1) 非MFC动态库
指不使用MFC类库创建的DLL。Win32 DLL中的导出函数通常使用标准的C接口,这些函数可以被MFC或非MFC应用程序调用。
(2) MFC规则DLL
MFC规则DLL可以使用MFC来创建,可以导出C风格的函数,但不能导出C++类、成员函数或重载函数。它们可以被MFC或非MFC应用程序调用。但这种类型的DLL不能向应用程序传递MFC对象指针,必须使用MFC扩展DLL。MFC常规DLL按照与MFC的链接方式又分动态链接和静态链接两种。
(3) MFC扩展DLL
表面上更像应用程序而不像一组函数的集合,因为它可以创建MFC派生类。只能以动态方式与MFC链接,而且只能是使用MFC的动态链接版本的应用程序才可以使用这种DLL。在MFC扩展DLL中,可以由现有的MFC类导出自己的类,然后给应用程序一个扩展的MFC版本。支持C++接口,也就是说,该DLL可以导出整个类,客户可以构造这些类的对象或从这些类进行派生。还可以用于在应用程序和DLL之间传递MFC导出对象。对象的成员函数位于创建对象的模块中,应用程序和它加载的扩展DLL之间可以自如地传递MFC或MFC导出对象的指针。
接下来,我们一起来具体讨论一下以上三种动态链接库的创建方法与调用方法。
二、非MFC动态链接库
2.1. Non-MFC DLL动态链接库的创建
在Visual C++6.0开发环境下,打开File/New/Project选项,可以选择Win32 Dynamic-Link Library或MFC AppWizard[dll] 来以不同的方式来创建Non-MFC Dll、Regular Dll、Extension Dll等不同种类的动态链接库。下面演示以Win32 Dynamic-Link
5
VC++环境下动态链接库的开发及应用
Library方式创建一个简单Non-MFC Dll工程“MyDll”。
2.1.1. 创建一个Non-MFC Dll工程“MyDll”
(1)在Visual C++6.0开发环境下,打开File/New/Project选项,选择Win32 Dynamic-Link Library创建一个简单DLL工程,并命名为“MyDll”。
图2-1-1 创建Non-MFC Dll工程“MyDll”
(2)在建立的工程中添加lib.h及lib.cpp文件,源代码如下: /* 文件名:lib.h */ #ifndef LIB_H #define LIB_H extern \ int __declspec(dllexport)multi(int x,int y); #endif /* 文件名:lib.cpp */ #include \int multi(int x,int y) { return x*y; }
6
VC++环境下动态链接库的开发及应用
显然,以上建立的是一个返回两个数的乘积的动态链接库。
(3)建立一个与MyDll工程处于同一工作区的应用工程DllCall。
图2-1-2 创建应用工程“DllCall”
在工程“DllCall”创建源代码文件“DllCall.cpp”,它调用DLL中的函数multi,其源代码如下: #include
HINSTANCE hDll; //DLL句柄 lpmultiFunc multiFunc; //函数指针 hDll = LoadLibrary(\if (hDll != NULL) { multiFunc = (lpmultiFunc)GetProcAddress(hDll, \if (multiFunc != NULL) { int result = multiFunc(3,5); //计算3与5的乘积 printf(\7
VC++环境下动态链接库的开发及应用
} }
FreeLibrary(hDll); return 0; (4)编译,运行结果如下:
图2-1-3 运行结果
如上图所示,成功返回3*5的结果,表明此NON-MFC DLL创建成功。
2.1.2. 代码分析
分析上述代码,Mydll工程中的lib.h对函数multi的声明前面添加了__declspec(dllexport)语句。这个语句的含义是声明函数multi为DLL的导出函数。DLL内的函数分为两种: (1) DLL导出函数,可供应用程序调用;
(2) DLL内部函数,只能在DLL程序使用,应用程序无法调用它们。
现在分析应用工程dllCall 对 DLL 的调用是如何实现的:
首先,语句typedef int ( * lpmultiFun)(int,int)定义了一个与multi函数接受参数类型和返回值均相同的函数指针类型。随后,在main函数中定义了lpmultiFunc的实例multiFunc;
其次,在函数main中定义了一个DLL HINSTANCE句柄实例hDll,通过Win32 Api函数LoadLibrary动态加载了DLL模块并将DLL模块句柄赋给了hDll;
再次,在函数main中通过Win32 Api函数GetProcAddress得到了所加载DLL模块中函数multi的地址并赋给了multiFunc。经由函数指针multiFunc进行了对DLL中add函数的调用;
8