在Windows编程中,进程间通信是一项非常重要的任务,它允许不同的进程之间共享数据和资源。WinAPI提供了多种函数来实现进程间通信(IPC),其中最常用的是CreatePipe函数。
CreatePipe函数提供了创建一个无名管道的功能,这是一种允许一个进程将输出发送到另一个进程的机制。通过该函数,我们可以简单地实现两个进程之间双向通信的需求。在本文中,我们将重点介绍如何使用CreatePipe函数实现进程间通信。
CreatePipe函数的具体定义如下:
```C++
BOOL CreatePipe(
PHANDLE hReadPipe,
PHANDLE hWritePipe,
LPSECURITY_ATTRIBUTES lpPipeAttributes,
DWORD nSize
);
```
它有四个参数,其中:
- hReadPipe和hWritePipe是一个指向HANDLE类型的指针,分别指向一个读管道和一个写管道。读管道只能用于读取数据,写管道只能用于写入数据。这两个参数是CreatePipe函数输出的,因此当函数返回时,它们指向已经创建的管道。
- lpPipeAttributes是一个指向SECURITY_ATTRIBUTES结构的指针,可以用来设置管道的安全属性(如果您不需要设置安全属性,可以传递NULL)。
- nSize是管道的缓冲区大小,以字节为单位。如果为0,则会设置为默认值。
在调用CreatePipe函数时,我们需要指定这4个参数,然后函数将创建一个匿名管道,并将读管道和写管道的句柄传递给我们。
接下来,我们来看一个示例程序,该程序演示了如何使用CreatePipe函数实现进程间通信。
```C++
#include
#include
using namespace std;
int main()
{
HANDLE hReadPipe, hWritePipe;
DWORD dwRead, dwWrite;
CHAR szMessage[] = "Hello, World\n";
CHAR szBuffer[1024];
SECURITY_ATTRIBUTES sa = { 0 };
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
// 创建管道
if (!CreatePipe(&hReadPipe, &hWritePipe, &sa, 0))
{
cerr << "CreatePipe Failed : " << GetLastError() << endl;
return 0;
}
// 创建子进程
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi = { 0 };
si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = hReadPipe;
si.hStdOutput = hWritePipe;
si.hStdError = hWritePipe;
if (!CreateProcess(NULL, "child.exe", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
{
cerr << "CreateProcess Failed : " << GetLastError() << endl;
return 0;
}
// 父进程向子进程发送消息
if (!WriteFile(hWritePipe, szMessage, sizeof(szMessage), &dwWrite, NULL))
{
cerr << "WriteFile Failed : " << GetLastError() << endl;
return 0;
}
// 读取子进程回复的消息
if (!ReadFile(hReadPipe, szBuffer, sizeof(szBuffer), &dwRead, NULL))
{
cerr << "ReadFile Failed : " << GetLastError() << endl;
return 0;
}
// 输出子进程回复的消息
cout << "Received Message : " << szBuffer << endl;
// 关闭管道和进程句柄
CloseHandle(hReadPipe);
CloseHandle(hWritePipe);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
}
```
在这个示例程序中,我们使用CreatePipe函数创建一个匿名管道,并将读管道和写管道句柄传递给子进程。然后,父进程向子进程写入一条消息("Hello, World\n"),然后读取子进程回复的消息,最后输出读取到的消息。
值得注意的是,此示例程序演示了如何在两个不同的进程中进行通信。也就是说,我们使用CreateProcess函数创建了一个新的进程,将读管道和写管道的句柄传递给它。这样,子进程就可以从读管道中读取父进程发送的数据,并从写管道中向父进程发送数据。
这里再强调一下上面的示例程序中一个重要的点:我们在启动子进程时使用了STARTF_USESTDHANDLES标志,这是为了将标准输入、输出和错误的句柄指定到CreatePipe函数返回的读管道和写管道句柄。这样,我们就可以通过这些标准句柄与子进程进行交互了。
总结一下,使用CreatePipe函数可以非常方便地实现进程间通信。它提供了创建一个无名管道的功能,我们只需要传入一些参数就可以创建一个管道,使用返回的句柄与另一个进程进行通信。此外,我们在示例程序中还介绍了如何使用CreateProcess函数创建一个新的进程,并将管道句柄传递给它。这种方法可以在出现需要不同进程之间进行通信的情况时使用。