Text-Ausgabe umleiten auf eine Konsole



  • In einem C++ Programm (fensterlose Schachengine, die via Universal Chess Interface mit einer Schach-GUI kommuniziert) möchte ich Ausgaben real-time durchführen. Dazu habe ich wie folgt eine Konsole erstellt und möchte dort etwas ausgeben:

      //Zusätzliche Konsole starten
      STARTUPINFO si;
      PROCESS_INFORMATION pi;
      ZeroMemory(&si, sizeof(si));
      si.cb = sizeof(si);
      ZeroMemory(&pi, sizeof(pi));
    
      HANDLE pipe_out, pipe_in, pipe_err;
        
      pipe_out = CreateFile(TEXT("\\\\.\\pipe\\Pipe"),
          GENERIC_WRITE | GENERIC_READ,
          0,
          NULL,
          OPEN_EXISTING,
          0,
          NULL);
      
      CreatePipe(&pipe_in, &pipe_err, 0, 0);
    
      si.dwFlags |= STARTF_USESTDHANDLES;
      si.hStdInput = pipe_in;
      si.hStdOutput = pipe_out;
      si.hStdError = pipe_err;
    
      CreateProcess(
          NULL, // No module name (use command line). 
          (LPSTR)"cmd", // Command line. 
          NULL,             // Process handle not inheritable. 
          NULL,             // Thread handle not inheritable. 
          FALSE,            // Set handle inheritance to FALSE. 
          0,                // No creation flags. 
          NULL,             // Use parent's environment block. 
          NULL,             // Use parent's starting directory. 
          &si,              // Pointer to STARTUPINFO structure.
          &pi               // Pointer to PROCESS_INFORMATION structure.
      );
      
      char str[12] = "Hello Pipe\n";
      DWORD dwWritten = 12;
    
      if (pipe_out != INVALID_HANDLE_VALUE)
      {
          ReadFile(
              pipe_out,
              str,
              dwWritten,
              &dwWritten,
              NULL);
    
          //CloseHandle(pipe_out);
      }  
    

    Da kommt leider nix an. Kenne mich da nicht aus. Kann mir jemand helfen, wie man auf die erstellte Konsole Ausgaben durchführt? Im Netz habe ich nichts vollständiges gefunden, daher der Krampf.



  • AllocConsole();
    freopen_s((FILE**)stdout, "CONOUT$", "w", stdout);
    

    ?



  • Funktioniert gut für meine Ausgaben. Die Engine haut aber nun alles dorthin, wodurch die GUI sie rauswirft. Ich muss also hin und her schalten. Wie geht das?

    Alternativ verwende ich momentan cerr. Das geht gut für kurze Ausgaben.

    AllocConsole();
      freopen_s((FILE**)stderr, "CONOUT$", "w", stderr);
    
      std::cerr << engine_info() << std::endl;
      std::cerr << "hello" << std::endl;
    
    

    Für längere Ausgaben müsste ich die Ausgabe wohl threadsicher machen. Tipp?



  • Hilft es vielleicht schon wenn Du stdout und stderr mit setvbuf() unbuffered machst?



  •   setvbuf(stdout, NULL, _IONBF, 0); // turn off buffering for stdout
      setvbuf(stderr, NULL, _IONBF, 0); // turn off buffering for stdcerr
        
      AllocConsole();
      freopen_s((FILE**)stderr, "CONOUT$", "w", stderr);
    
      std::cerr << engine_info() << std::endl;
      std::cerr << "Hallo! Hier gibt es real-time Kommentare zum Spiel.\n" << std::endl;
    

    Ist das so ok?

    Ich verwende dann std::cerr an verschiedenen Stellen für eigene Ausgaben.
    Hier gebe ich eine kleine Tabelle aus, klappt bisher.

    std::cerr << token << "\n" << Eval::trace(pos) << "\n" << std::endl; 
    


  • Ich würde das setzten des Puffers für stderr nach freopen_s() machen. Garantien gebe ich bei dem ganzen aber keine auf garnichts ^^



  • Danke für die Tipps! Sehr hilfreich.


Log in to reply