2012-11-28 84 views
1

我有一個運行java進程並讀取它的輸出的C++程序。 ,讀取當輸出C++讀取java進程輸出

bSuccess = ReadFile(g_hInputFile, chBuf, BUFSIZE, &dwRead, NULL); 

bsucces等於1的最後一行,所以程序繼續到下一個循環,並在到達時

http://msdn.microsoft.com/en-us/library/ms682499%28v=vs.85%29.aspx

然而: 我用下面MSDN代碼同一行,程序只是「飛」,無一例外地停下來調試,斷點從不移動到下一行。

我想這是因爲沒有EOF來表明停止閱讀。 但是,java 沒有一個EOF charcater。 java程序簡單地做:

System.out.close(); 

在結束。

我可以在C++ \ Java代碼中做些什麼來解決它?

編輯:

這裏是代碼。

它不適用於任何控制檯應用程序,讀取結束然後「掛起」。

HANDLE g_hChildStd_IN_Rd = NULL; 
HANDLE g_hChildStd_IN_Wr = NULL; 
HANDLE g_hChildStd_OUT_Rd = NULL; 
HANDLE g_hChildStd_OUT_Wr = NULL; 

HANDLE g_hInputFile = NULL; 
PROCESS_INFORMATION piProcInfo; 

void CreateChildProcess() 
// Create a child process that uses the previously created pipes for STDIN and STDOUT. 
{ 
    std::string d=processLoaction; 
    TCHAR *cmdline=new TCHAR[d.size()+1]; 
    cmdline[d.size()]=0; 
    std::copy(d.begin(),d.end(),cmdline); 
    STARTUPINFO siStartInfo; 
    BOOL bSuccess = FALSE; 

// Set up members of the PROCESS_INFORMATION structure. 

    ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION)); 

// Set up members of the STARTUPINFO structure. 
// This structure specifies the STDIN and STDOUT handles for redirection. 

    ZeroMemory(&siStartInfo, sizeof(STARTUPINFO)); 
    siStartInfo.cb = sizeof(STARTUPINFO); 
    siStartInfo.hStdError = g_hChildStd_OUT_Wr; 
    siStartInfo.hStdOutput = g_hChildStd_OUT_Wr; 
    siStartInfo.dwFlags |= STARTF_USESTDHANDLES; 

// Create the child process. 
    bSuccess = CreateProcess(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &siStartInfo, &piProcInfo); // receives PROCESS_INFORMATION 

    // If an error occurs, exit the application. 
    if (! bSuccess) 
     throw new Exception("Failed to create process"); 
    else 
    { 
     // Close handles to the child process and its primary thread. 
     // Some applications might keep these handles to monitor the status 
     // of the child process, for example. 

     CloseHandle(piProcInfo.hProcess); 
     CloseHandle(piProcInfo.hThread); 
    } 
} 

void ReadFromPipe(void) 
// Read output from the child process's pipe for STDOUT 
// and write to the parent process's pipe for STDOUT. 
// Stop when there is no more data. 
{ 
    DWORD dwRead, dwWritten,status; 
    CHAR chBuf[BUFSIZE]; 
    BOOL bSuccess = FALSE; 
    HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE); 
    BOOL res; 
    for (;;) 
    { 
     bSuccess = ReadFile(g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL); 
     if(! bSuccess || dwRead == 0) 
      break; 
     chBuf[dwRead] = NULL; 
     bSuccess = WriteFile(hParentStdOut, chBuf, dwRead, &dwWritten, NULL); 
     if (! bSuccess) 
      break; 
    } 

} 

int main(int argc, char** argv) 
{ 
      //run the Jar to validate manifest & jeff 
      SECURITY_ATTRIBUTES saAttr; 

      // Set the bInheritHandle flag so pipe handles are inherited. 
      saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
      saAttr.bInheritHandle = TRUE; 
      saAttr.lpSecurityDescriptor = NULL; 

      // Create a pipe for the child process's STDOUT. 
      if (! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0)) 
       throw new Exception("faild to create a pipe for the child process's STDOUT"); 

      // Ensure the read handle to the pipe for STDOUT is not inherited. 
      if (! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0)) 
       throw new Exception("Read handle to the pipe for STDOUT is inherited"); 
      CreateChildProcess(); 
      ReadFromPipe(); 
      ... 
} 
+0

EOF不是一個字符。 – melpomene

+0

您確定您正在閱讀正確的文件/句柄嗎? - 在示例代碼中,通過'bSuccess = ReadFile(g_hChildStd_OUT_Rd,chBuf,BUFSIZE,&dwRead,NULL);'從子進程讀取數據。 – JimmyB

+0

@HannoBinder是的,所有的行被成功讀取,並寫入我自己的控制檯。最後,我只是離開了「掛」 – sara

回答

1

這個問題似乎在你的鏈接頁面的一些意見加以解決:您可以選擇創建子進程後關閉管道的寫的一面,但開始從另一個側面讀數。如果你沒有這樣做,即使子進程關閉了它的輸出,管道的寫入端仍然是打開的(通過父進程),所以永遠不會到達EOF。

啊,不要忘記關閉父進程的所有句柄。鏈接頁面中的示例不會,並且會泄漏!

+0

我不使用寫管...只讀 – sara

+0

@sara:即使你不使用它,你有句柄,你必須關閉它。只要有任何書寫手柄打開,管道本身就不會被標記爲EOF。 – rodrigo