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); }
运行结果如下图所示: