我使用 C++ 编写了两个进程。一种是我的控制台应用程序使用CreateProcess
API 调用的 GUI 进程。我需要将文本从 GUI 应用程序(子级)传递到控制台应用程序(父级)。文本的数量可以是任意的——从几行到 KB 的文本。
最简单的方法是什么?
PS。我可以访问这两个进程的源代码。
我使用 C++ 编写了两个进程。一种是我的控制台应用程序使用CreateProcess
API 调用的 GUI 进程。我需要将文本从 GUI 应用程序(子级)传递到控制台应用程序(父级)。文本的数量可以是任意的——从几行到 KB 的文本。
最简单的方法是什么?
PS。我可以访问这两个进程的源代码。
控制台应用程序可以创建一个 WinAPI 窗口(不可见),以便它可以接收消息(取自 Delphi 中的 AllocateHWND 函数的想法)。
另一种解决方案是使用命名管道。
另一种解决方案是通过 TCP/IP 在本地发送数据。
如果这些字符串只是调试字符串,请考虑使用 WinAPI 中的 OutputDebugString 函数并使用 SysInternals 的DbgView之类的程序捕获它们。
最简单的方法可能是让孩子实际上是一个控制台应用程序,即使它也创建了窗口。
在这种情况下,您可以让您的父母使用 产生孩子_popen
,而孩子可以将输出写入其正常stdout
/ std::cout
。_popen
返回 a FILE *
,因此父级可以像通常读取文件一样读取子级的输出(好吧,通常对于 C 来说)。
如果 GUI 应用程序真正只是图形化的,那么您就不会真正使用标准输出流(即std::cout
)。这可以重复用于输出到您的控制台应用程序。
首先,您需要使用以下命令创建一个匿名管道CreatePipe
:
HANDLE hPipeRead;
HANDLE hPipeWrite;
CreatePipe(&hPipeRead, &hPipeWrite, NULL, 0);
现在您必须处理可以用作普通文件句柄的句柄;一个用于读取,另一个用于写入。写句柄应设置为您创建的新进程的标准输出:
STARTUPINFO startupInfo = { 0 };
startupInfo.cb = sizeof(startupInfo);
startupInfo.dwFlags = STARTF_USESTDHANDLES;
startupInfo.hStdOutput = hPipeWrite; // Standard output of the new process
// is set to the write end of the pipe
CreateProcess(
lpApplicationName,
lpCommandLine,
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&startupInfo, // Use our startup information
&processInfo);
现在每当子进程需要写入父进程时,它只需要使用标准输出:
std::cout << "In child process, are you getting this parent?";
父级用于ReadFile
从管道的读取端读取:
char buffer[256];
DWORD bytesRead = 0;
ReadFile(hPipeRead, buffer, sizeof(buffer), &bytesRead, NULL);
注意:我有一段时间没有做过WIN32编程,所以可能有些细节有误。但希望足以让你开始。
进程间通信(IPC)当然还有很多其他方式,包括(但不限于)套接字、文件、共享内存等。
可以使用各种方法,其中一些已在上面给出。哪个最简单取决于您的任务。
我还可以建议您在 IPC 中广泛使用的文件映射技术,例如。dll 是使用文件映射实现的。
它允许多个进程同时共享相同的资源,访问是随机的而不是必然的。
以下是实现的主要步骤:
1.进程A创建文件;
2.进程A为文件创建一个命名系统对象mappedfile(mappedfile分配内存);
3.进程 A 创建一个系统对象 viewOfMapped 文件(这允许将进程 A 的某些区域映射到由 mappedFile 分配的主内存中的页面);
4.进程B创建命名系统对象mappedfile(名称应该与进程A使用的相似),viewOfMapped文件;
5.通过viewOfMapped进程返回的指针可以共享相同的内存。示例:
过程 A:
/* 1. file creation */
hFile = CreateFile(0, GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
NULL);
/* 2. Create file mapping */
wchar_t lpName[] = L"fileMappingObject0";
HANDLE hfileMappingObject;
hfileMappingObject = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 1024, lpName);
/* 3. Create MappedFileViewOfFile */
void* p = (MapViewOfFile(hfileMappingObject, FILE_MAP_ALL_ACCESS, 0, 0, 0));
过程乙:
/* 2. Create file mapping */
wchar_t lpName[] = L"fileMappingObject0";
HANDLE hfileMappingObject;
hfileMappingObject = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 1024, lpName);
/* 3. Create MappedFileViewOfFile */
void* p = (MapViewOfFile(hfileMappingObject, FILE_MAP_ALL_ACCESS, 0, 0, 0));
这种方法比较简单,也很强大。