2012-11-28 85 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