MFC C++进程间通信-匿名管道(上)

这是我第一次出教程,若不好可在评论回复我哦(・。・)~~~~~

注:匿名管道是一个未命名的单相管道,通常用来在一个父进程和一个子进程之间的传输数据。匿名管道只能实现本地机器上两个进程间的通讯,却不能实现网络的通讯。

  1. 打开编译器VS2019
  2. 创建MFC应用程序
  3. 设置项目名称“Parent”,解决方案名称为“进程间通讯-匿名管道”
    MFC C++进程间通信-匿名管道(上)

4.应用程序类型选择“基于对话框”
MFC C++进程间通信-匿名管道(上)
5. 用户界面功能选中“最小化框”“最大化框”,再去掉“ ‘关于’框”。
MFC C++进程间通信-匿名管道(上)

  1. 点击“完成”
  2. 绘制窗口。

MFC C++进程间通信-匿名管道(上)
“启动子进程”设置属性,在“杂项”里修改ID——IDC_BTN_BEGIN

MFC C++进程间通信-匿名管道(上)

“写入数据”设置属性,在“杂项”里修改ID——IDC_BTN_WRITE

MFC C++进程间通信-匿名管道(上)
“读取数据”设置属性,在“杂项”里修改ID——IDC_BTN_READ
MFC C++进程间通信-匿名管道(上)

  1. 双击“启动子进程”在“OnBnClickedBtnBegin()”

创建两个成员变量:

HANDLE m_hRead;
HANDLE m_HWrite;

记得在构造函数里初始化一下哦~~~~~~~~

  • CreatePipe函数:
BOOL CreatePipe(
  PHANDLE hReadPipe,
  PHANDLE hWritePipe,
  LPSECURITY_ATTRIBUTES lpPipeAttributes,
  DWORD nSize
);

hReadPipe
[out] 指向接收管道读取句柄的变量的指针。

hWritePipe
[out] 指向接收管道写句柄的变量的指针。

lpPipeAttributes
[in]指向SECURITY_ATTRIBUTES结构的指针,该结构确定子进程是否可以继承返回的句柄。 如果 lpPipeAttributes 为 NULL,则不能继承句柄。
该结构的 lpSecurityDescriptor 成员为新管道指定了一个安全描述符。 如果 lpPipeAttributes 为 NULL,则管道获得一个默认的安全描述符。 管道的默认安全描述符中的 ACL 来自创建者的主要令牌或模拟令牌。

nSize
[in] 管道缓冲区的大小,以字节为单位。 尺寸只是一个建议; 系统使用该值来计算适当的缓冲机制。 如果此参数为零,则系统使用默认缓冲区大小。

// TODO: 在此添加控件通知处理程序代码
	SECURITY_ATTRIBUTES sa;
	sa.bInheritHandle = TRUE;
	sa.lpSecurityDescriptor = NULL;
	sa.nLength = sizeof(sa);

	//创建匿名管道
	if (!CreatePipe(&m_hRead, &m_hWrite, &sa, 0))
	{
		MessageBox(L"创建匿名管道失败.Error", L"", MB_OK | MB_ICONERROR);
		return;
	}

	STARTUPINFO si = { 0 };
	si.cb = sizeof(STARTUPINFO);
	si.dwFlags = STARTF_USESTDHANDLES;
	si.hStdInput = m_hRead;
	si.hStdOutput = m_hWrite;
	si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
	PROCESS_INFORMATION pi;

	//创建子进程
	if (!CreateProcess(L"Sub.exe", NULL, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi))
	{
		CloseHandle(m_hRead);
		CloseHandle(m_hWrite);
		m_hRead = NULL;
		m_hWrite = NULL;
		MessageBox(L"创建Sub.exe", L"温馨提示", MB_OK | MB_ICONERROR);
		return;
	}
	else
	{
		CloseHandle(pi.hProcess);
		CloseHandle(pi.hThread);
	}

注:必须要用父进程启动子进程,不能单独启动子进程!!!

  1. 对话框中双击“写入数据”,在“OnBnClickedBtnRead()”中
// TODO: 在此添加控件通知处理程序代码
	wchar_t szBuffer[100] = { 0 };
	DWORD dwRead;
	if (!ReadFile(m_hRead, szBuffer, sizeof(szBuffer), &dwRead, NULL))
	{
		MessageBox(L"ReadFile Error");
		return;
	}
	MessageBox(szBuffer);
  1. 对话框中双击“读取数据”,在“OnBnClickedBtnWrite()”中
// TODO: 在此添加控件通知处理程序代码
	wchar_t szBuffer[] = L"Hello!——父进程";
	DWORD dwWrite = 0;

	if (!WriteFile(m_hWrite, szBuffer, wcslen(szBuffer) * 2 + 1, &dwWrite, NULL))
	{
		MessageBox(L"WriteFile Error!", L"");
		return;
	}
上一篇:Windows 消息机制详解


下一篇:Linux 信号编程