操作系统——MFC实现进程创建和通信3

本文介绍了如何在MFC中使用WM_COPYDATA消息进行进程间通信,包括消息发送原理、COPYDATASTRUCT结构的使用,并讨论了其局限性。随后,文章转向大型数据传输的解决方案,如内存共享和管道通信,以拓宽通信范围。
摘要由CSDN通过智能技术生成

引入

我接着上篇博客讲,如果没有构建项目的童鞋请移步到操作系统——MFC实现进程创建和通信1
用PostMessage实现通信请移步到操作系统——MFC实现进程创建和通信2
实现进程通信的方法有很多,这篇博客使用WM_COPYDATA消息完成进程间通信。

用WM_COPYDATA消息实现通信

通信原理

进程A发送WM_COPYDATA消息给进程B

SendMessage(接收窗口句柄, WM_COPYDATA, (WPARAM)发送窗口句柄, (LPARAM)&copyData);

其中的copyData是要发送的数据,类型为COPYDATASTRUCT结构体:

typedef struct tagCOPYDATASTRUCT

{

DWORD dwData;

DWORD cbData;

PVOID lpData;

} COPYDATASTRUCT;

dwData : Specifies up to 32 bits of data to be passed to the receiving application.

cbData : Specifies the size, in bytes, of the data pointed to by the lpData member.

lpData : Long pointer to data to be passed to the receiving application. This member can be NULL.

该消息只能由SendMessage()发送,而不能使用PostMessage()。因为系统必须管理用以传递数据的缓冲区的生命期,如果使用了PostMessage(),数据缓冲区会在接收方(线程)有机会处理该数据之前,就被系统清除和回收。
如果传入的接收窗口句柄无效或者当接收方进程意外终止时,SendMessage()会立即返回,发送方不会陷入一个无穷等待的状态中。

MainProcess中添加发送函数

在资源视图中双击Button进入到点击事件函数的处理中。
在这里插入图片描述
在处理函数中添加以下代码完成Copydata消息的发送。

void CMFCApplication1Dlg::OnBnClickedOk4()
{
	LRESULT copyDataResult;
	CString strDataToSend;//要传输的内容
	GetDlgItemText(IDC_EDIT1, strDataToSend);//从控件获取内容
	CWnd* pOtherWnd = CWnd::FindWindow(_T("#32770"), _T("ChildProcess"));//获取进程句柄
	if (pOtherWnd)
	{
		COPYDATASTRUCT cpd;//可以传输到其他进程的结构体
		cpd.cbData = 2 * strDataToSend.GetLength();//数据长度,注意乘2
		cpd.lpData = strDataToSend.GetBuffer(); //数据指针
		copyDataResult = pOtherWnd->SendMessage(WM_COPYDATA, (WPARAM)AfxGetApp()->m_pMainWnd->GetSafeHwnd(), (LPARAM)&cpd);//发送
		strDataToSend.ReleaseBuffer();//销毁
	}
	else
	{
		AfxMessageBox(_T("没有找到子进程"));
	}
}

Copydata这个消息通过sendMessage方法发送给进程B后,进程A就不在拥有Copydata的句柄。

在ChildProcessDlg.cpp中添加发送函数

直接右键点击childProcess通过类向导添加COPYDATA消息处理函数(框架自动添加的,总比自己填一堆要好,框架会帮忙在头文件添加声明我们只用写定义方便很多)
在这里插入图片描述
在这里插入图片描述
最后点击添加处理程序就可以在ChildProcess实现文件中看到定义了,也可以直接点击编辑代码加上以下代码:

BOOL CChileProcessDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
	if (pCopyDataStruct->cbData > 0)
	{
		char recvData[1024] = { 0 };
		memcpy(recvData, (char*)pCopyDataStruct->lpData, pCopyDataStruct->cbData);
		CString str;
		str.Format(_T("%s"), recvData);
		SetDlgItemText(IDC_EDIT1, str);
	}
	return CDialogEx::OnCopyData(pWnd, pCopyDataStruct);
}

重新生成一下ChildProcess项目,编译运行

在这里插入图片描述


WM_COPYDATA消息是通过用户自定义一个结构体,然后进程A通过SendMessge方法将这个结构体发送给进程B从而实现进程通信的。
由于结构体最多也就那么大,所以Copydata不适合用来传输大型消息,接下来我会介绍大型消息传输常用的方法—内存共享和管道通信。
操作系统——MFC实现进程创建和通信4

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AlbertOS

还会有大爷会打钱?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值