【问题标题】:Wait on serial receive event and console input event in Windows API等待 Windows API 中的串行接收事件和控制台输入事件
【发布时间】:2016-07-10 00:41:03
【问题描述】:

我是一名中级 C++ 程序员,但我不熟悉使用 Windows 的 API 函数。

我正在尝试创建一个控制台程序,它会一直坐/睡到任何一个

  1. 用户在控制台中输入内容并按下回车键
  2. 在已打开的串行端口上接收串行数据

四处搜索,听起来在 Windows 中执行此操作的方法是使用事件,(听起来它们与中断的基本概念相同?)

我找到了有关 WaitCommEvent 的文档,并且阅读了有关读取控制台输入缓冲区事件的信息。我猜要使用的函数是 WaitForMultipleObjects,但是我发送它的具体处理是什么,所以它会等待串行 RX 事件或控制台标准输入事件?

更新: 感谢您的回复!

目前我一直在使用 std::cin/cout 来读取和写入控制台。我查看了您提到的控制台 API 并看到了 GetStdHandle 函数,它将提供您提到的 CONIN$ 句柄。我可以将 CONIN$handle 发送到等待函数,而不是像您建议的那样使用 CreateFile 并手动使用 ReadFile/Console API 吗?

对于串行,我知道如何将串行句柄打开为 OVERLAPPED 而不是 NONOVERLAPPED,但我不确定您的意思

修改同步 I/O 代码以使用通常并不难 一个异步句柄

这样的?

uint32 read(HANDLE serialHandle, uint8* pBuffer, int32 bufferLenght)
{
  DWORD dwBytesRead;

  if (!ReadFile(SerialHandle, pBuffer, bufferLength, &dwBytesRead, NULL))
  { /*ERROR*/ }
  else
  {
    // Wait on some flag or variable until read is complete 
    // to make this call synchronous/NONOVERLAPPED ?
    return static_cast<uint32>(dwBytesRead);
  }    
}

在读取完成之前,该标志将等待什么/在哪里?

【问题讨论】:

  • GetStdHandle 不一定会为您提供控制台句柄,如果您的程序是在标准输入(和/或标准输出和/或标准错误)重定向的情况下启动的。因此,如果您知道自己想要控制台,那么它不是最佳选择。对于重叠 I/O,您必须传递一个 OVERLAPPED 结构,包括一个事件句柄。

标签: c++ winapi


【解决方案1】:

来自 MSDN 上的Low-Level Console Input Functions

应用程序进程的线程可以执行等待操作以等待输入缓冲区中的输入可用。要启动等待操作,请在调用任何等待函数时指定输入缓冲区的句柄。

因此您需要使用控制台句柄,您可以通过在CONIN$ 上调用 CreateFile 来获得该句柄。您还需要使用相同的句柄,通过 ReadFile 或控制台 API 来读取控制台输入;由于缓冲,使用运行时库函数可能会搞砸你。

对于串口,我相信你需要使用异步 I/O。 WaitCommEvent 函数(当提供异步模式句柄时)接受包含手动重置事件对象句柄的 OVERLAPPED 结构。然后,您将在调用 WaitForMultipleObjects 时使用相同的事件句柄。

不幸的是,这是全有或全无,因此您必须在异步模式下打开 COM 句柄并独占使用异步 I/O。 (幸运的是,修改同步 I/O 代码以使用异步句柄通常并不难,尽管如果有很多 I/O 调用,您可能需要编写一个包装函数来完成构建 OVERLAPPED 的重复工作结构并等待操作完成。)

【讨论】:

  • "所以只需使用控制台句柄,与您用于读取控制台输入的句柄相同。" - 您假设 OP 正在使用低端的句柄从console input buffer 开始,例如从CreateFile("CONIN$"),而不是更高的级别,例如std::cin
  • @HarryJohnson:大多数人直接使用低级 API 编写控制台应用程序,例如控制台输入/输出缓冲区 API。他们使用在内部封装 API 的高级框架,通常是编译器提供的 RTL。
  • 我的意思是,您的回答对 OP 当前 使用什么做出了假设,希望它满足等待要求,而不是告诉OP 需要什么来满足要求。
猜你喜欢
  • 1970-01-01
  • 2017-06-04
  • 2017-02-03
  • 1970-01-01
  • 1970-01-01
  • 2010-12-02
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
相关资源
最近更新 更多