这些代码行确保内部使用的MFC变量或添加到类的变量是从扩展DLL导出(或导入)的。例如,当使用DECLARE_DYNAMIC派生类时,该宏扩展以将CRuntimeClass成员变量添加到类。省去这四行代码可能会导致不能正确编译或链接DLL,或在客户端应用程序链接到DLL时导致错误。
当生成DLL时,链接器使用.def文件创建导出(.exp)文件和导入库(.lib)文件。然后,链接器使用导出文件生成DLL文件。隐式链接到DLL的可执行文件在生成时链接到导入库。请注意,MFC本身就是使用.def文件从MFCx0.dll导出函数和类的。
2.关键字或宏
除了使用DEF文件来导出函数外,还可以在源程序中使用__declspec(dllexport)关键字或其替代宏AFX_EXT_CLASS:
#define AFX_EXT_CLASS AFX_CLASS_EXPORT (定义在头文件afxv_dll.h中) #define AFX_CLASS_EXPORT __declspec(dllexport) (定义在头文件afxver_.h中)
来导出函数和整个C++类。
具体的格式为: ? 导出整个类:
class AFX_EXT_CLASS 类名[ : public基类] { }
? 导出类的成员函数:
class 类名[ : public基类] { }
? 导出外部C格式的(全局)函数:
extern \返回类型 函数名(??) {
??
AFX_EXT_CLASS 返回类型 函数名1(??) ; AFX_EXT_CLASS 返回类型 函数名2(??) ; ??
??
6
}
如果希望用MFC(C++)编写的规则DLL中的函数,也能够被非MFC程序来调用,需要为函数声明指定extern \。不然,C++编译器会使用C++类型安全命名约定(也称作名称修饰)和C++调用约定(使用此调用约定从C调用会很困难)。
为了使用方便,可以定义宏:
#define DllExport extern \
然后再使用它,例如:
DllExport int Add(int d1, int d2) {??}
20.2 扩展DLL
使用MFC编写的扩展DLL,可以导出整个类(从而能使用类中的所有成员,包括数据成员和成员函数),也可以导出指定的若干(成员或全局)函数。
下面我们通过一个四则运算的例子,看看如何用宏AFX_EXT_CLASS来编写和使用导出整个C++类的扩展MFC DLL。
20.2.1 创建DLL项目
我们创建一个名为ExtDll的扩展DLL的“Visual C++”之“MFC”的“MFC DLL”项目,注意需选中“创建解决方案的目录”复选框,参见图20-2。
7
图20-2 新建MFC DLL项目ExtDll的对话框
按“确定”钮,弹出“MFC DLL向导”对话框。在“DLL类型”栏中,选中“扩展DLL”单选钮,参见图20-3。按“完成”钮,创建ExtDll解决方案和项目。
图20-3 选择“扩展DLL”的MFC DLL向导对话框
20.2.2 添加导出类
为新项目添加用于四则计算的导出类CCompute。方法有多种,可以在项目管理区的“类视图”页中,选中项目名“ExtDll”,按鼠标右键,在弹出菜单中选“添加\\类”。在弹出的“添加类”对话框中,选择“Visual C++”之“MFC”的“MFC类”项,参见图20-4。
8
图20-4 添加类对话框
按“添加”钮,弹出“MFC类向导”对话框。在“类名”栏中键入“CCompute”,在“基类”下拉式列表,选“CObject”,参见图20-5。按“完成”钮,添加该类到ExtDll项目。
图20-5 MFC类向导对话框
9
20.2.3 编写导出类代码
我们将整个CCompute类设为导出类,并在里面添加2个成员变量、1个构造函数和4个用于四则运算的成员函数,外加1个演示导出函数的取模全局函数Mod。
下面是CCompute类的头文件(Compute.h),其中红色的部分是自己添加:(注意导出宏AFX_EXT_CLASS的使用)
#pragma once
// CCompute 命令目标
class AFX_EXT_CLASS CCompute : public CObject { public:
int m_data1, m_data2;
public:
CCompute();
CCompute(int d1, int d2); virtual ~CCompute();
public: };
AFX_EXT_CLASS int Mod(int d1, int d2);
下面是CCompute类的代码源文件(Compute.cpp),其中红色为自己添加的部分:
// Compute.cpp : 实现文件 //
#include \
10
int Add(); int Sub(); int Mul(); double Div();