街角_祝福

导航

动态链接库(DLL)--MFCDLL

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);
}

运行结果如下图所示:




posted on 2012-12-10 23:00  街角_祝福  阅读(180)  评论(0编辑  收藏  举报