2010-12-29 16 views
4

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.Verwenden von überlappenden IO für Konsoleneingabe?

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

Hier ist der Code, den ich mit:

// 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; 
}
+0

Funktioniert es auf anderen Windows-Versionen? – Mehrdad

Antwort

4

Beim Öffnen CONIN$ oder CONOUT$ die Parameter dwFlagsAndAttributes ignoriert werden (in der Dokumentation der CreateFile Funktion ist eine vollständige Beschreibung darüber, wie die Konsole zu öffnen). Wenn Sie die Konsole asynchron lesen möchten, können Sie das von CreateFile zurückgegebene Handle direkt an die WaitForSingleObject-Funktion übergeben. Wenn ein Konsolenereignis aussteht, wird dieses Handle signalisiert, wobei Sie die ausstehenden Ereignisse mit der Funktion ReadConsoleInput lesen. Here ist die vollständige Dokumentation der Verwendung der Konsole in Windows.

+0

Diese Antwort scheint keinen Sinn zu machen. Das Übergeben eines Handles an WaitForSingleObject() lässt asynchrones IO nicht zu, da dieser Aufruf offensichtlich blockiert. – Kyberias

+0

@Kyberias: Nicht, wenn Sie eine Zeitüberschreitung von Null bestehen. Dann gibt der Rückgabewert an, ob die Eingabewarteschlange leer ist oder nicht. –

Verwandte Themen