7

FILE_FLAG_OVERLAPPED フラグを指定して CONIN$ を開いて、オーバーラップ IO を使用してコンソールから入力を読み取ろうとしています。ただし、OVERLAPPED パラメータを使用しても、ReadFile を使用するとブロックされます。

これが 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;
}
4

1 に答える 1

6

開いた場合、CONIN$またはCONOUT$パラメーターdwFlagsAndAttributesが無視された場合 ( CreateFile関数のドキュメントには、コンソールを開く方法に関する完全な説明があります)。コンソールを非同期的に読み取りたい場合は、返されたハンドルCreateFileを関数に直接渡すことができます。WaitForSingleObject保留中のコンソール イベントがある場合は、このハンドルが通知されます。関数ReadConsoleInputを使用して、保留中のイベントを読み取ります。 これは、Windows でコンソールを使用する方法の完全なドキュメントです。

于 2010-12-29T08:13:58.610 に答える