You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows下如何用C/C++编写程序执行外部程序并接收其返回信息?

Windows下C++实现子进程启动与进程间通信

你的需求完全可以通过C/C++实现,Windows平台下最适合这个场景的方案是匿名管道(Anonymous Pipe),它能让父进程(程序1)和子进程(程序2)之间单向传递数据,刚好匹配「程序1启动程序2,程序2发数据给程序1后退出」的流程。

核心实现思路

  1. 父进程创建一对匿名管道:一端用于读取子进程的输出,另一端让子进程写入数据
  2. 父进程通过CreateProcess启动子进程,将子进程的标准输出重定向到管道的写入端
  3. 子进程启动后,直接向标准输出(stdout)写入要传递的信息,随后退出
  4. 父进程从管道的读取端读取子进程发送的数据,完成通信

代码示例

父进程(程序1)代码

#include <windows.h>
#include <iostream>
#include <string>

int main() {
    HANDLE hReadPipe, hWritePipe;
    SECURITY_ATTRIBUTES sa = {0};
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = TRUE; // 允许子进程继承管道句柄

    // 创建匿名管道
    if (!CreatePipe(&hReadPipe, &hWritePipe, &sa, 0)) {
        std::cerr << "CreatePipe failed, error: " << GetLastError() << std::endl;
        return 1;
    }

    STARTUPINFO si = {0};
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags = STARTF_USESTDHANDLES;
    si.hStdOutput = hWritePipe; // 将子进程的stdout重定向到管道写入端
    si.hStdError = hWritePipe;  // 可选:把子进程的stderr也重定向过来

    PROCESS_INFORMATION pi = {0};
    // 启动子进程(替换为你的程序2路径,比如"./program2.exe")
    if (!CreateProcess(
        NULL,
        (LPSTR)"./program2.exe",
        NULL,
        NULL,
        TRUE, // 继承父进程的句柄
        0,
        NULL,
        NULL,
        &si,
        &pi
    )) {
        std::cerr << "CreateProcess failed, error: " << GetLastError() << std::endl;
        CloseHandle(hReadPipe);
        CloseHandle(hWritePipe);
        return 1;
    }

    // 关闭父进程端的写入管道(子进程还持有它,不影响)
    CloseHandle(hWritePipe);

    // 读取子进程发送的数据
    char buffer[1024];
    DWORD bytesRead;
    std::string receivedData;
    while (ReadFile(hReadPipe, buffer, sizeof(buffer)-1, &bytesRead, NULL) && bytesRead > 0) {
        buffer[bytesRead] = '\0';
        receivedData += buffer;
    }

    std::cout << "Received from program2: " << receivedData << std::endl;

    // 等待子进程退出,清理资源
    WaitForSingleObject(pi.hProcess, INFINITE);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    CloseHandle(hReadPipe);

    return 0;
}

子进程(程序2)代码

#include <iostream>

int main() {
    // 直接向stdout写入要传递的信息
    std::cout << "Hello from Program 2! This is the data I want to send." << std::endl;
    // 用fflush确保数据立即写入管道,避免缓冲
    fflush(stdout);
    // 程序自动退出,完成流程
    return 0;
}

关键细节说明

  • 管道继承:创建管道时sa.bInheritHandle必须设为TRUE,同时CreateProcess的第5个参数设为TRUE,这样子进程才能继承管道句柄。
  • 句柄关闭:父进程启动子进程后要立即关闭自己持有的写入管道句柄,否则读取管道的ReadFile会一直等待,直到所有写入端都关闭。
  • 数据缓冲:子进程如果用C++的cout,可能会有缓冲,所以用fflush(stdout)强制刷新,确保数据立刻发送到管道。
  • 错误处理:代码里的GetLastError可以帮助排查创建管道或启动进程时的问题。

除了匿名管道,你也可以用命名管道、共享内存等方式,但匿名管道是这个场景下最简单高效的选择。

内容的提问来源于stack exchange,提问作者Nico Cano

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 05:05:16