cwindowswindows-consolewin64

Opening Windows console for stdin/stdout/stderr for both of win32 and win64 in C


First of all, I'm not a Windows programmer (not even a Windows user), I use cross-compiler on Linux to build also for Win32 and Win64. After digging the Net (and even asking a question here) I've managed to put a code fragment together which can open a windows console, and use it for stdin/stdout/stderr. It works well with Win32, but the program crashes on Win64. I guess the problem is the different long integer data type size, gcc even warns about this. However since I don't know the exact purpose and size of some windows API types, so I can't figure out what I should change. Surely, the best would be some win32/win64 independent solution. I also tried to use the "HANDLE" type for lStdHandle but then it even does not compile. Can anyone help about this?

    int hConHandle;
    long lStdHandle;
    //HANDLE lStdHandle;
    CONSOLE_SCREEN_BUFFER_INFO coninfo;
    FILE *fp;
    FreeConsole(); // be sure to release possible already allocated console
    if (!AllocConsole()) {
            ERROR_WINDOW("Cannot allocate windows console!");
            return;
    }
    SetConsoleTitle("My Nice Console");
    // set the screen buffer to be big enough to let us scroll text
    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
    coninfo.dwSize.Y = 1024;
    //coninfo.dwSize.X = 100;
    SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
    // redirect unbuffered STDOUT to the console
    lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
    hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
    fp = _fdopen( hConHandle, "w" );
    *stdout = *fp;
    setvbuf( stdout, NULL, _IONBF, 0 );
    // redirect unbuffered STDIN to the console
    lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
    hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
    fp = _fdopen( hConHandle, "r" );
    *stdin = *fp;
    setvbuf( stdin, NULL, _IONBF, 0 );
    // redirect unbuffered STDERR to the console
    lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
    hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
    fp = _fdopen( hConHandle, "w" );
    *stderr = *fp;
    setvbuf( stderr, NULL, _IONBF, 0 );
    // Set Con Attributes
    //SetConsoleTextAttribute(GetStdHandle(STD_ERROR_HANDLE), FOREGROUND_RED | FOREGROUND_INTENSITY);
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_INTENSITY);
    SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT);
    SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT);

Solution

  • It is a handle so you should use the HANDLE type. Cast to INT_PTR (or SIZE_T if your SDK is really outdated) when you call _open_osfhandle, using long can truncate the value!