【问题标题】:Using overlapped IO for console input?使用重叠 IO 进行控制台输入?
【发布时间】:2011-05-31 21:36:32
【问题描述】:

我正在尝试使用重叠 IO 从控制台读取输入,方法是使用 FILE_FLAG_OVERLAPPED 标志打开 CONIN$。但是,当我使用 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;
}

【问题讨论】:

  • 在其他版本的 Windows 上也可以使用吗?

标签: winapi visual-c++ io overlapped-io


【解决方案1】:

当您打开CONIN$CONOUT$ 时,参数dwFlagsAndAttributes 将被忽略(在CreateFile 函数的文档中完整描述了如何打开控制台)。如果您喜欢异步读取控制台,您可以将CreateFile 返回的句柄直接传递给WaitForSingleObject 函数,如果有任何控制台事件未决,则会发出此句柄的信号,使用函数ReadConsoleInput 你是否读取了未决的事件。 Here 是关于如何在 windows 中使用控制台的完整文档。

【讨论】:

  • 这个答案似乎没有任何意义。将句柄传递给 WaitForSingleObject() 不允许异步 IO,因为该调用显然会阻塞。
  • @Kyberias:如果超时时间为零,则不会。然后返回值告诉你输入队列是否为空。
猜你喜欢
  • 1970-01-01
  • 2012-09-28
  • 2012-04-25
  • 1970-01-01
  • 1970-01-01
  • 2021-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多