2

我写了一个简单的测试文件:

#include "iostream"
using namespace std;

int main(int argc, char const *argv[]) {
    char s[512];
    while(cin >> s) {
        for(int i=0; s[i]; ++i) {
            s[i] ^= 32;
        }
        cout << s << endl;
    }
    return 0;
}

在另一个程序中,我想将它作为子进程启动并使用管道与它通信。我CreatePipe用来创建两个管道,并使用CreateProcess重定向的 stdio 标志启动它。

创建管道的代码:

HANDLE _stdin_rd = NULL;
HANDLE _stdin_wr = NULL;
HANDLE _stdout_rd = NULL;
HANDLE _stdout_wr = NULL;

BOOL br;

SECURITY_ATTRIBUTES sa;
PROCESS_INFORMATION gdb_info;   // the process information

void _init() {
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = TRUE;   // the handles are inheritable
    sa.lpSecurityDescriptor = NULL;

    // Create stdin pipe.
    br = CreatePipe(&_stdin_rd, &_stdin_wr, &sa, NULL);
    if(!br) {
        cerr << "Can't create stdin pipe." << endl;
        abort();
    }
    // ensure the write handle to the pipe for stdin is not inherited.
    br = SetHandleInformation(_stdin_wr, HANDLE_FLAG_INHERIT, 0);
    if(!br) {
        cerr << "change stdin pipe attr error" << endl;
        abort();
    }

    // Create stdout pipe.
    br = CreatePipe(&_stdout_rd, &_stdout_wr, &sa, NULL);
    if(!br) {
        cerr << "Can't create stdout pipe." << endl;
        abort();
    }
    // ensure the read handle to the pipe for stdout is not inherited.
    br = SetHandleInformation(_stdout_rd, HANDLE_FLAG_INHERIT, 0);
    if(!br) {
        cerr << "change stdout pipe attr error" << endl;
        abort();
    }
}

void _launch() {
    STARTUPINFO si;
    ZeroMemory(&si, sizeof(STARTUPINFO));
    ZeroMemory(&gdb_info, sizeof(PROCESS_INFORMATION));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags |= STARTF_USESTDHANDLES; // so as to enable text pipe
    si.hStdInput = _stdin_rd;       // redirection
    si.hStdOutput = _stdout_wr;
    si.hStdError = _stdout_wr;

    br = CreateProcess(
        NULL,
        "test",     // command line 
        NULL,       // process security attributes 
        NULL,       // primary thread security attributes 
        TRUE,       // handles are inherited 
        NULL,       // creation flags 
        NULL,       // use parent's environment 
        NULL,       // use parent's current directory 
        &si,        // STARTUPINFO pointer 
        &gdb_info   // receives PROCESS_INFORMATION 
    );
    if(!br) {
        cerr << "Can't start test file!" << endl;
        abort();
    } else {
        cout << "test file invoked." << endl
            << "Process " << gdb_info.dwProcessId << endl
            << "Thread " << gdb_info.dwThreadId << endl;
    }
}

void test_loop() {
    HANDLE console_out = GetStdHandle(STD_OUTPUT_HANDLE);
    char buf[512];
    DWORD len;

    WriteFile(gdb_stdin_wr, "Helloworld", strlen("Helloworld"), &len, NULL);
    ReadFile(gdb_stdout_rd, buf, 512, &len, NULL);
    WriteFile(console_out, buf, len, &len, NULL);
    //
    WriteFile(_stdin_wr, "PipeCommuni", strlen("PipeCommuni"), &len, NULL);
    ReadFile(_stdout_rd, buf, 512, &len, NULL);
    WriteFile(console_out, buf, len, &len, NULL);
    //
    WriteFile(gdb_stdin_wr, "HAHAhehe", strlen("HAHAhehe"), &len, NULL);
    ReadFile(gdb_stdout_rd, buf, 512, &len, NULL);
    WriteFile(console_out, buf, len, &len, NULL);
}

问题是,在我启动程序后,它成功启动了测试程序。但是程序只是卡在那里,没有报告错误。

如果我将命令行“test”更改为“gdb”之类的程序,那么我可以接收来自 gdb 的输出。

谁能帮我解决这个问题?

4

0 回答 0