Использование перекрывающегося ввода-вывода для ввода с консоли? - PullRequest
5 голосов
/ 29 декабря 2010

Я пытаюсь использовать перекрывающийся ввод-вывод для чтения ввода с консоли, открыв CONIN $ с флагом FILE_FLAG_OVERLAPPED. Однако ReadFile блокирует, когда я его использую, даже с параметром OVERLAPPED.

Я прочитал несколько сообщений о том, что это ошибка Windows 7. Я использую 7, чтобы это было возможно.

Вот код, который я использую:

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

1 Ответ

5 голосов
/ 29 декабря 2010

При открытии CONIN$ или CONOUT$ параметр dwFlagsAndAttributes игнорируется (в документации к функции CreateFile приведено полное описание того, как открыть консоль). Если вы хотите читать консоль асинхронно, вы можете передать дескриптор, возвращенный CreateFile, напрямую в функцию WaitForSingleObject, и если какое-либо событие консоли ожидает, этот дескриптор будет сигнализирован с помощью функции ReadConsoleInput do Вы читаете ожидающие события. Здесь - полная документация по использованию консоли в Windows.

...