2

我使用 C++ 编写了两个进程。一种是我的控制台应用程序使用CreateProcessAPI 调用的 GUI 进程。我需要将文本从 GUI 应用程序(子级)传递到控制台应用程序(父级)。文本的数量可以是任意的——从几行到 KB 的文本。

最简单的方法是什么?

PS。我可以访问这两个进程的源代码。

4

4 回答 4

3

控制台应用程序可以创建一个 WinAPI 窗口(不可见),以便它可以接收消息(取自 Delphi 中的 AllocateHWND 函数的想法)。

另一种解决方案是使用命名管道。

另一种解决方案是通过 TCP/IP 在本地发送数据。

如果这些字符串只是调试字符串,请考虑使用 WinAPI 中的 OutputDebugString 函数并使用 SysInternals 的DbgView之类的程序捕获它们。

于 2013-03-15T07:27:40.010 回答
1

最简单的方法可能是让孩子实际上是一个控制台应用程序,即使它也创建了窗口。

在这种情况下,您可以让您的父母使用 产生孩子_popen,而孩子可以将输出写入其正常stdout/ std::cout_popen返回 a FILE *,因此父级可以像通常读取文件一样读取子级的输出(好吧,通常对于 C 来说)。

于 2013-03-15T07:18:54.603 回答
1

如果 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)当然还有很多其他方式,包括(但不限于)套接字、文件、共享内存等。

于 2013-03-15T09:22:13.383 回答
1

可以使用各种方法,其中一些已在上面给出。哪个最简单取决于您的任务。
我还可以建议您在 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));

这种方法比较简单,也很强大。

于 2013-03-15T09:54:11.913 回答