2011-01-26 5 views
1

パイプからの読み取りのために例文hereに従っていますが、ReadFileは失敗し、GetLastError()はパイプが壊れていることを示しています。
私は以前にプログラムでパイプを作成して使用しましたが、すべてのハンドルを閉じ、確実に新しいパイプ用に全く新しい変数を使用しました。
これはなぜ機能しないのでしょうか?win32(WinAPI)のパイプ破損

HANDLE g_hChildStd_OUT_Rd2 = NULL; 
HANDLE g_hChildStd_OUT_Wr2 = NULL; 
SECURITY_ATTRIBUTES saAttr2; 
STARTUPINFO si2; 
PROCESS_INFORMATION pi2; 

ZeroMemory(&si2, sizeof(si2)); 
si2.cb = sizeof(si2); 
ZeroMemory(&pi2, sizeof(pi2)); 
//create pipe 
saAttr2.nLength = sizeof(SECURITY_ATTRIBUTES); 
saAttr2.bInheritHandle = TRUE; 
saAttr2.lpSecurityDescriptor = NULL; 
CreatePipe(&g_hChildStd_OUT_Rd2, &g_hChildStd_OUT_Wr2, &saAttr2, 0); 
//create child process 
bSuccess = FALSE; 
memset(szCmdLine, 0, MAX_PATH); 
sprintf(szCmdLine, "ffmpeg.exe -i output.mp3"); 
ZeroMemory(&pi2, sizeof(PROCESS_INFORMATION)); 
ZeroMemory(&si2, sizeof(STARTUPINFO)); 
si2.cb = sizeof(STARTUPINFO); 
si2.hStdOutput = g_hChildStd_OUT_Wr2; 
si2.dwFlags |= STARTF_USESTDHANDLES; 
CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si2, &pi2); 
//read from pipe 
CloseHandle(g_hChildStd_OUT_Wr2); 
memset(chBuf, 0, BUFSIZE); 
for (;;) 
{ 
    bSuccess = ReadFile(g_hChildStd_OUT_Rd2, chBuf, BUFSIZE, &dwRead, NULL); 
    [bSuccess is 0 and GetLastError() returns error 109] 
    ........ 
+1

ので、我々は問題を見つけるために私たちのコンパイラを使用することができ、最小限のが、完全なソースコードを投稿してください。 full =コンパイルして実行できます。最小=あなたの問題を再現するのに十分なコードしかありません –

答えて

3

「破損パイプ」は、もう一方のパイプが閉じたときの通常のエラーです。あなたのケースでは、これは、 "他端"がないか、または他のアプリケーションがstdoutに何も書いていないことを意味します。 私は、コンパイル、テストケースのようにコードを修正しました - ReadFileが私のために任意のデータを読み取るせずに失敗した2例があります。

  • CreateProcessに失敗しましたが。問題を認識できるようにassertを追加しました。もちろんパイプが壊れてしまうでしょう。
  • プロセスは何も標準出力に書き出しません。代わりに、標準エラーストリームに書き込むことができます。私はstderrをパイプにリダイレクトしました。私のechoの例では、これはパイプのもう一方の端に両方のストリームを受け取ります。

コード:

#define WIN32_LEAN_AND_MEAN 
#include <Windows.h> 
#include <assert.h> 
#include <stdio.h> 
#include <string.h> 

#define BUFSIZE 200 

int main(void) 
{ 
    BOOL bSuccess; 
    char szCmdLine[MAX_PATH]; 
    char chBuf[BUFSIZE]; 
    DWORD dwRead; 
    HANDLE g_hChildStd_OUT_Rd2 = NULL; 
    HANDLE g_hChildStd_OUT_Wr2 = NULL; 
    SECURITY_ATTRIBUTES saAttr2; 
    STARTUPINFO si2; 
    PROCESS_INFORMATION pi2; 

    ZeroMemory(&si2, sizeof(si2)); 
    si2.cb = sizeof(si2); 
    ZeroMemory(&pi2, sizeof(pi2)); 
    //create pipe 
    saAttr2.nLength = sizeof(SECURITY_ATTRIBUTES); 
    saAttr2.bInheritHandle = TRUE; 
    saAttr2.lpSecurityDescriptor = NULL; 
    assert(CreatePipe(&g_hChildStd_OUT_Rd2, &g_hChildStd_OUT_Wr2, &saAttr2, 0)); 
    //create child process 
    bSuccess = FALSE; 
    memset(szCmdLine, 0, MAX_PATH); 
    sprintf(szCmdLine, "cmd /c echo output && echo error>&2"); 
    ZeroMemory(&pi2, sizeof(PROCESS_INFORMATION)); 
    ZeroMemory(&si2, sizeof(STARTUPINFO)); 
    si2.cb = sizeof(STARTUPINFO); 
    si2.hStdOutput = g_hChildStd_OUT_Wr2; 
    si2.hStdError = g_hChildStd_OUT_Wr2; // also add the pipe as stderr! 
    si2.dwFlags |= STARTF_USESTDHANDLES; 
    assert(CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si2, &pi2)); 
    //read from pipe 
    CloseHandle(g_hChildStd_OUT_Wr2); 
    memset(chBuf, 0, BUFSIZE); 
    for (;;) 
    { 
     bSuccess = ReadFile(g_hChildStd_OUT_Rd2, chBuf, BUFSIZE, &dwRead, NULL); 
     printf("%d %lu 0x%08lx\n", bSuccess, dwRead, GetLastError()); 
     if (bSuccess) 
      printf("\t'%*s'\n", (int)dwRead, chBuf); 
     else 
      break; 
    } 
    return 0; 
} 
+0

申し訳ありませんが、*遅くとも遅く受け付けますが、問題のあるコードを見つけて実際に何が問題になったのか見ていました。この問題は実際には、呼び出された実行ファイルffmpeg.exeがstdoutに何も印刷していないという事実でした。 – Claudiu

関連する問題