• Lunes 29 de Abril de 2024, 00:59

Autor Tema:  INVALID_HANDLE redireccionando cin,cout,cerr  (Leído 1195 veces)

krnl64

  • Miembro activo
  • **
  • Mensajes: 72
    • Ver Perfil
INVALID_HANDLE redireccionando cin,cout,cerr
« en: Jueves 9 de Septiembre de 2010, 21:02 »
0
Hola,  estoy escribiendo una pequeña clase para abrir una consola en programas con interfaz gráfica y usarla para emitir información de depuración.
Por comodidad, intento redirigir los flujos de la consola para poder usar cin, cout y cerr en vez de apis para leer y escribir en ella
El código que les presento yo diria que es correcto, pero no se comporta bien en ejecución.

Si hago un cin, ya no escribe nada en pantalla al usar cout. Sólo si uso cerr y escribe todo lo que haya en el buffer.
En vista de estos fallos, uso GetLastError después de hacer cin, y me dice INVALID_HANDLE_VALUE.
No entiendo por qué se cierra el handle.

Edit:
Pruebas hasta ahora sin resultado:
1º Obtener el handles de entrada, salida y error con GetStdHandle en el constructor. Intentar restaurarlos con SetConsoleActiveScreenBuffer. cout sigue sin escribir en consola.
2º Cerrar el handle de salida con CloseHandle, volver a abrirlos con GetStdHandle y usar cout. Aqui GetLastError dice que no hay error, pero no se escribe nada en consola
3º Abrir los flujos de consola CONIN$,CONOUT$,CONERR$ con CreateFile. Restaurarlos con SetConsoleActiveScreenBuffer y usar cout. GetLastError dice INVALID_HANDLE y no se escribe nada en consola

Pueden decirme qué es lo que hago mal ?

PD: uso W Xp SP3 y VC++ 2008

Gracias

console.h
Código: C++
  1.  
  2. // console.h
  3. #ifndef __CONSOLE_H__
  4. #define __CONSOLE_H__
  5.  
  6. #include <iostream>
  7. #include <fstream>
  8.  
  9. using std::cout;
  10. using std::cin;
  11. using std::cerr;
  12.  
  13. using std::streambuf;
  14. using std::ofstream;
  15. using std::ifstream;
  16.  
  17.  
  18. class console
  19. {
  20.  
  21.     private:
  22.    
  23.         ofstream n_cout;
  24.         ofstream n_cerr; // new streams
  25.         ifstream n_cin;
  26.  
  27.         streambuf* old_cout;
  28.         streambuf* old_cerr; // old streams
  29.         streambuf* old_cin;
  30.  
  31.     public:
  32.    
  33.         console();
  34.         ~console();
  35.  
  36.         void hide();
  37.         void show(); // not implemented yet
  38. };
  39. #endif
  40.  
  41.  

console.cpp
Código: C++
  1.  
  2. #include "console2.h"
  3. #include <windows.h>
  4.  
  5. console::console()
  6. {
  7.    
  8.     // create a console window
  9.     AllocConsole();
  10.  
  11.     // redirect cout to console window
  12.     this->old_cout = cout.rdbuf(); 
  13.     this->n_cout.open("CONOUT$");   
  14.     cout.rdbuf( this->n_cout.rdbuf() );
  15.    
  16.     // redirect cerr
  17.     this->old_cerr = cerr.rdbuf();
  18.     this->n_cerr.open("CONOUT$");
  19.     cerr.rdbuf( this->n_cerr.rdbuf() );
  20.  
  21.     // redirect cin
  22.     this->old_cin = cin.rdbuf();
  23.     this->n_cin.open("CONIN$");
  24.     cin.rdbuf( this->n_cin.rdbuf() );
  25.    
  26. }
  27.  
  28. console::~console()
  29. {
  30.     // restore streams
  31.     cin.rdbuf( this->n_cin.rdbuf() );
  32.     cerr.rdbuf( this->n_cerr.rdbuf() );
  33.     cout.rdbuf( this->n_cout.rdbuf() );
  34.    
  35.   // free console resources
  36.   FreeConsole();
  37. }
  38.  
  39.  

// main.cpp
Código: C++
  1.  
  2.  
  3. #include <windows.h>
  4.  
  5. int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
  6. {
  7.  
  8. // all WNDCLASSEX, RegisterClassEx,CreateWindow, etc stuff
  9.  
  10.  console c;
  11.  int number = 0;
  12.  
  13. cout << "n cout works";
  14. cerr << "n cerr works";
  15. cin >> number; // cin works
  16.  
  17. DWORD error = GetLastError(); // INVALID_HANDLE_VALUE ¿ por qué ?
  18.  
  19. cout << "n The number is: " << number;  // Esto ya no funciona
  20.  
  21. cerr << number; // ahora escribe todo lo que haya en el buffer
  22. }
  23.  
  24.