1.MFCDL创建
选择MFCDLL工程类型的项目,创建即可。
创建成功后,由于此DLL为MFCDLL,所以可以使用MFC类库、可以添加对话框,功能较丰富。我在实验中创建的MFCDLL是一个会监视USB的对话框DLL。
工程创建完了之后,可以像MFC一样添加对话框,并在对话框上建立类向导重写虚函数、响应消息,本次的DLL(MFCDll)为USB监视的窗口,所以创建了CListen类,并重写窗口的消息过程函数,如下所示:
LRESULT CListen::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: 在此添加专用代码和/或调用基类
switch (message)
{
case WM_DEVICECHANGE:
{
CString str;
str.Format(TEXT("检测到移动设备"));
if(wParam == DBT_DEVICEREMOVECOMPLETE)
{
str += TEXT("移除\r\n");
MessageBox(str, NULL, MB_OK | MB_ICONINFORMATION);
}
if(wParam == DBT_DEVICEARRIVAL)
{
str += TEXT("插入\r\n");
MessageBox(str, NULL, MB_OK | MB_ICONINFORMATION);
}
break;
}
default:
break;
}
return CDialog::WindowProc(message, wParam, lParam);
}
之后,需要定义该MFC DLL的对外接口,需要在MfcDll.cpp内定义声明,如下所示:
extern "C" __declspec(dllexport) BOOL Listen(BOOL bStart)
{
//这一句必须加,且加在最前面
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CListen dlgUSB;
dlgUSB.DoModal();
return TRUE;
}
尤其需要注意的是,需要在接口函数内的第一个语句处放置AFX_MANAGE_STATE(AfxGetStaticModuleState());,该语句是用来切换模块资源的。如果没有该语句,那么会在调用该DLL的时候会出错。定义了对外接口之后,需要在dll的def文件中声明该导出函数,直接添加该函数名字就可以了,如下所示:
; MFCDll.def : 声明 DLL 的模块参数。
LIBRARY
EXPORTS
; 此处可以是显式导出
Listen
这样,一个MFC的DLL便完成了。
由MFC的DLL创建可以发现,他的过程和Non-MFCDLL有不同点的,Non-MFC的DLL的导出函数的声明是在头文件中,而MFC的则是在def'文件中,不过MFC应该也可以使用Non-MFC的方式的。此外需要注意的是在MFC的对外接口函数内添加哪一行模块资源切换语句。
2.MFC的DLL的调用
对于MFC的DLL的使用一般使用显示调用方法,这和Non-MFCDLL一样,不过可以发现MFC的DLL既可以被MFC的程序调用,也可以被控制台的程序调用。部分调用代码如下:
MFC程序调用
void CMFCLoadAllDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
//MFC DLL
typedef BOOL (*pListen)();
HINSTANCE hDll = NULL;
//加载DLL
hDll = ::LoadLibrary(TEXT("../../MfcDll/Debug/MfcDll.dll"));
if(hDll == NULL)
{
MessageBox(TEXT("MfcDll.dll加载失败!"), TEXT("错误"), MB_OK | MB_ICONERROR);
return;
}
//声明导出函数指针
pListen pListenProc = NULL;
//通过GetProcAddress获取导出函数地址并赋值给指针
pListenProc = (pListen)::GetProcAddress(hDll, "Listen");
//检查获取情况,成功,则调用函数
if(pListenProc == NULL)
{
MessageBox(TEXT("MfcDll.dll文件内找不到导出函数Listen"), TEXT("找不到导出函数"), MB_OK | MB_ICONINFORMATION);
}
else
{
pListenProc();
}
//释放加载的DLL
::FreeLibrary(hDll);
}
控制台应用程序调用
//MFC DLL
void TestMFCDll()
{
typedef BOOL (*pListen)();
HINSTANCE hDll = NULL;
//加载DLL
hDll = ::LoadLibrary(TEXT("../../MfcDll/Debug/MfcDll.dll"));
if(hDll == NULL)
{
MessageBox(NULL, TEXT("MfcDll.dll加载失败!"), TEXT("错误"), MB_OK | MB_ICONERROR);
return;
}
//声明导出函数指针
pListen pListenProc = NULL;
//通过GetProcAddress获取导出函数地址并赋值给指针
pListenProc = (pListen)::GetProcAddress(hDll, "Listen");
//检查获取情况,成功,则调用函数
if(pListenProc == NULL)
{
MessageBox(NULL, TEXT("MfcDll.dll文件内找不到导出函数Listen"), TEXT("找不到导出函数"), MB_OK | MB_ICONINFORMATION);
}
else
{
pListenProc();
}
//释放加载的DLL
::FreeLibrary(hDll);
}
运行结果如下图所示: