Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 保持连接打开时多次读取匿名管道(WinAPI)_C++_Winapi_Io_Pipe_Readfile - Fatal编程技术网

C++ 保持连接打开时多次读取匿名管道(WinAPI)

C++ 保持连接打开时多次读取匿名管道(WinAPI),c++,winapi,io,pipe,readfile,C++,Winapi,Io,Pipe,Readfile,所以我一直在命名管道和匿名管道之间跳跃,这是我的问题。我尝试了命名管道,但它们似乎无法满足我的需求,所以我又回到了匿名管道。但是,匿名管道需要将输入从管道读取到我没有创建的程序,并在管道有更多可用信息时继续读取。以下是我目前拥有的相关代码: void Arc_Redirect::createProcesses() { TCHAR programName[]=TEXT("program.exe"); PROCESS_INFORMATION pi; STARTUPINFO

所以我一直在命名管道和匿名管道之间跳跃,这是我的问题。我尝试了命名管道,但它们似乎无法满足我的需求,所以我又回到了匿名管道。但是,匿名管道需要将输入从管道读取到我没有创建的程序,并在管道有更多可用信息时继续读取。以下是我目前拥有的相关代码:

void Arc_Redirect::createProcesses()
{
    TCHAR programName[]=TEXT("program.exe");
    PROCESS_INFORMATION pi; 
    STARTUPINFO si;

    SECURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = NULL;

    if(!CreatePipe(&outStd[0].hOutRead,&outStd[0].hOutWrite,&sa,0) || !CreatePipe(&outStd[0].hInRead,&outStd[0].hInWrite,&sa,0))
        throw "Error: Could not CreatePipe();!";

    if(!SetHandleInformation(outStd[0].hOutRead,HANDLE_FLAG_INHERIT,0) || !SetHandleInformation(outStd[0].hInWrite,HANDLE_FLAG_INHERIT,0))
        throw "Error: Could not SetHandleInformation();";


    // Set stuff up
    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO); 
    si.hStdError = outStd[0].hOutWrite;
    si.hStdOutput = outStd[0].hOutWrite;
    si.hStdInput = outStd[0].hInRead;
    si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;

    outStd[0].o1.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

    if(!CreateProcess(programName,NULL,NULL,NULL,TRUE,0,NULL,NULL,&si,&pi))
        throw "Error: Could not start Program!";

    // Cleanup the useless handles
    if(!CloseHandle(pi.hThread) || !CloseHandle(pi.hProcess))
        throw "Error: Could not CloseHandle();";
}
下面是我如何阅读管道的:

void Arc_Redirect::readPipe()
{
    CHAR chBuf[BUFSIZE];
    DWORD dwRead;

    ReadFile(outStd[0].hOutRead,chBuf,sizeof(chBuf),&dwRead,&outStd[0].o1);
    chBuf[dwRead] = '\0';
    SetDlgItemText(global,IDO_WORLDOUT,chBuf);
    ResetEvent(outStd[0].o1.hEvent);

}
BUFSIZE定义为0x1000,EXTD定义为下面的管道句柄结构

typedef struct
{
    HANDLE hOutRead;
    HANDLE hOutWrite;
    HANDLE hInRead;
    HANDLE hInWrite;
    OVERLAPPED o1;
    TCHAR chReq[BUFSIZE];
    TCHAR chReply[BUFSIZE];
    DWORD dwRead;
    DWORD dwWritten;
    DWORD dwState;
    DWORD cbRet;
    BOOL pendingIO;
} PIPE_HANDLES, *LPSTDPIPE;
现在,我可以正确地调用readPipe;只要一次,它就完全符合我的要求。但是,如果我再次尝试调用它,它将失败。关于如何解决这个问题,有什么想法吗?正如我所说,我需要保持连接打开并以增量方式读取。为了便于辩论,假设我需要每5秒阅读一次;我正在读取的程序每5秒需要读取不同的输出。有什么帮助吗

问候,,
Dennis M.

如果你不找出原因,就不可能猜出它失败的原因。ReadFile失败时返回FALSE。然后应该调用GetLastError以获取诊断


永远不要忽略Windows API返回值。至少要声明它们。

ok我设置了BOOL bSuccess=ReadFile并添加了以下条件:if!b成功抛出GetLastError;然而,第一次它仍然可以工作,但是第二次它从未到达throw语句,但是程序冻结,这可能意味着ReadFile被挂起。有什么想法吗?是的,我的try{…}catch{…}语句被正确地设置为从我的readPipe捕获错误;我测试的功能。我刚切换到多线程。它使这项工作符合我的要求。谢谢你的帮助!