Frage Überlappende IO für Konsoleneingabe verwenden?


Ich versuche, überlappende IO zu verwenden, um Eingaben von der Konsole zu lesen, indem Sie CONIN $ mit dem Flag FILE_FLAG_OVERLAPPED öffnen. ReadFile blockiert jedoch, wenn ich es verwende, sogar mit einem OVERLAPPED-Parameter.

Ich habe einige Posts gelesen, die darauf hinweisen, dass dies ein Windows 7-Bug ist. Ich benutze 7, also könnte das möglich sein.

Hier ist der Code, den ich verwende:

// Create a console window
AllocConsole();
AttachConsole(GetProcessId(GetModuleHandle(NULL)));

HANDLE overlappedConsoleIn = CreateFile(L"CONIN$",
                              GENERIC_READ,
                              FILE_SHARE_READ,
                              NULL,
                              OPEN_EXISTING,
                              FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING,
                              NULL);

// Set up the console to work with stdio
FILE *consoleOut = _fdopen(_open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT), "w");
FILE *consoleIn = _fdopen(_open_osfhandle((long)overlappedConsoleIn, _O_TEXT), "r");

*stdout = *consoleOut;
*stdin = *consoleIn;

setvbuf(consoleOut, NULL, _IONBF, 0);
setvbuf(consoleIn, NULL, _IONBF, 0);

std::ios::sync_with_stdio();

// Create a completion event
HANDLE inputEvent = CreateEvent(NULL, true, false, NULL);

BYTE inputBuffer[128];

OVERLAPPED overlappedData;
overlappedData.Offset = 0;
overlappedData.OffsetHigh = 0;
overlappedData.hEvent = inputEvent;

DWORD numBytesRead = 0;

// Asynchronously read from console
ReadFile(overlappedConsoleIn, inputBuffer, 128, &numBytesRead, &overlappedData);

while(true)
{
    if(WaitForSingleObject(inputEvent, 0) == WAIT_OBJECT_0)
    {
        std::cout << "input has been received" << std::endl;
    }
    std::cout << "doing something" << std::endl;
}

5
2017-12-29 05:14


Ursprung


Antworten:


Wenn Sie öffnen CONIN$ oder CONOUT$ der Parameter dwFlagsAndAttributes wird ignoriert (in der Dokumentation des Erstelle Datei Funktion ist eine vollständige Beschreibung zum Öffnen der Konsole). Wenn Sie die Konsole asynchron lesen möchten, können Sie das von zurückgegebene Handle übergeben CreateFile direkt zum WaitForSingleObject Funktion und wenn irgendein Konsolenereignis aussteht, wird dieser Handle mit der Funktion signalisiert LeseConsoleInput Liest du die ausstehenden Ereignisse? Hier ist die vollständige Dokumentation der Verwendung der Konsole in Windows.


5
2017-12-29 08:13