二、建立DLL 利用Visual C++提供的向导功能可以很容易建立一个不完成任何实质任务的DLL,这里就不多讲了,主要的任务是如何给DLL添加功能,以及在客户程序中利用这个DLL1、导出类 用向导建立好框架后,就可以添加需要导出类的.cpp .h文件到DLL中来,或者用向导创建C++ Herder File/C++ Source File。为了能导出这个类,在类声明的时候要加“_declspec(dllexport)”,如:class _declspec(dllexport) CMyClass{ ...//声明}如果创建的MFC扩展DLL,可以使用宏:AFX_EXT_CLASS:class AFX_EXT_CLASS CMyClass{ ...//声明}这样导出类的方法是最简单的,也可以采用.def文件导出,这里暂不详谈。2、导出变量、常量、对象 很多时候不需要导出一个类,可以让DLL导出一个变量、常量、对象,导出它们只需要进行简单的声明:_declspec(dllexport) int MyInt; _declspec(dllexport) extern const COLORREF MyColor=RGB(0,0,0); _declspec(dllexport) CRect rect(10,10,20,20);要导出一个常量时必须使用关键字extern,否则会发生连接错误。注意:如果客户程序识别这个类而且有自己的头文件,则只能导出一个类对象。如果在DLL中创建一个类,客户程序不使用头文件就无法识别这个类。 当导出一个对象或者变量时,载入DLL的每个客户程序都有一个自己的拷贝。也就是如果两个程序使用的是同一个DLL,一个应用程序所做的修改不会影响另一个应用程序。 我们在导出的时候只能导出DLL中的全局变量或对象,而不能导出局部的变量和对象,因为它们过了作用域也就不存在了,那样DLL就不能正常工作。如:MyFunction(){ _declspec(dllexport) int MyInt; _declspec(dllexport) CMyClass object;}3、导出函数导出函数和导出变量/对象类似,只要把_declspec(dllexport)加到函数原型开始的位置:_declspec(dllexport) int MyFunction(int);如果是常规DLL,它将和C写的程序使用,声明方式如下:extern "c" _declspec(dllexport) int MyFunction(int);实现:extern "c" _declspec(dllexport) int MyFunction(int x){ ...//操作}如果创建的是动态连接到MFC代码库DLL的常规DLL,则必须插入AFX_MANAGE_STATE作为导出函数的首行,因此定义如下:extern "c" _declspec(dllexport) int MyFunction(int x){ AFX_MANAGE_STATE(AfxGetStaticModuleState()); ...//操作}有时候为了安全起见,在每个常规DLL里都加上,也不会有任何问题,只是在静态连接的时候这个宏无效而已。这是导出函数的方法,记住只有MFC扩展DLL才能让参数和返回值使用MFC的数据类型。4、导出指针导出指针的方式如下:_declspec(dllexport) int *pint;_declspec(dllexport) CMyClass object = new CMyClass;如果声明的时候同时初始化了指针,就需要找到合适的地方类释放指针。在扩展DLL中有个函数DllMain()。(注意函数名中的两个l要是小写字母),可以在这个函数中处理指针:# include "MyClass.h"_declspec(dllexport) CMyClass *pobject = new CMyClass;DllMain(HINSTANCE hInstance,DWORD dwReason,LPVOID lpReserved){ if(dwReason == DLL_PROCESS_ATTACH) { .....// } else if(dwReason == DLL_PROCESS_DETACH) { delete pobject; }}常规DLL有一个从CWinApp派生的类对象处理DLL的开和关,可以使用类向导添加InitInstance/ExitInstance函数。int CMyDllApp::ExitInstance(){ delete pobject; return CWinApp::ExitInstance();}三、在客户程序中使用DLL 编译一个DLL时将创建两个文件.dll文件和.lib文件。首先将这两个文件复制到客户程序项目的文件夹里,这里需要注意DLL和客户程序的版本问题,尽量使用相同的版本,都使用RELEASE或者都是DEBUG版本。 接着就需要在客户程序中设置LIB文件,打开Project Settings--->Link--->Object/library Modules中输入LIB的文件名和路径。如:Debug/SampleDll.lib。除了DLL和LIB文件外,客户程序需要针对导出类、函数、对象和变量的头文件,现在进行导入添加的关键字就是:_declspec(dllimport),如:_declspec(dllimport) int MyFunction(int);_declspec(dllimport) int MyInt;_declspec(dllimport) CMyClass object;extern "C" _declspec(dllimport) int MyFunction(int);在有的时候为了导入类,要把相应类的头文件添加到客户程序中,不同的是要修改类声明的标志:class _declspec(dllimport) CMyClass,如果创建的是扩展DLL,两个位置都是:class AFX_EXT_CLASS CMyClass。
