流着血和泪水,我刚刚发现每当您调用 GetCommState 时,DCB 结构的 fParity 成员都会主动设置为 FALSE。

是否有解决方法(除了明确设置 dcb.fParity = 1; 每次需要调用 SetCommState 时)?有没有人遇到过这个问题?是否有 MSDN 文章解释这种行为?

这是在我的 PC 上重现问题的 MCVE:

int main()
{
  HANDLE hComm;
  DCB dcb;

  // Replace COM1 by any COM port identifier on your PC
  hComm = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
  if (hComm == INVALID_HANDLE_VALUE)
  {
    printf("Failed COM opening. Exit.");
    return -1;
  }

  FillMemory(&dcb, sizeof(dcb), 0);
  dcb.DCBlength = sizeof(dcb);

  // Get the current DCB structure
  if (!GetCommState(hComm, &dcb))
  {
    printf("Failed GetCommState. Exit.");
    return -1;
  }

  // [Here, you may set any or all members of the dcb structure]
  // As suggested by chux and Hans Passant in a comment, try to set the parity to make the fParity value relevant.
  dcb.Parity = MARKPARITY;


  // This is the relevant bit :
  dcb.fParity = TRUE;

  // Set the new COM state.
  if (!SetCommState(hComm, &dcb))
  {
    printf("Failed SetCommState. Exit.");
    return -1;
  }

  // Read back the COM state (fParity should be TRUE)
  if (!GetCommState(hComm, &dcb))
  {
    printf("Failed GetCommState. Exit.");
    return -1;
  }

  printf("fParity = %d\n", dcb.fParity); // fParity value is 0.

  CloseHandle(hComm);
}

在 GetCommState() 之后没有正确读回的唯一值是 fParity。

最佳答案

我就此事联系了微软,半官方的回答是,是的,确实,DCB 结构的 fParity 成员存在错误,因为 GetCommState() 没有正确读回该值。 fParity 的值将始终为 false(即使文档说默认值为 true)。

他们还告诉我,驱动程序根本不检查 fParity 标志,并且根据 Parity 标志设置报告(或不报告)奇偶校验错误。

最后一点信息让我有点难受,因为关于 DCB 的 MSDN 页面特别指出结构的另一个成员 fErrorChar 除非 fParity 为真,否则不会生效。我从来没有得到关于 fErrorChar 行为的令人满意的解释。

我怀疑 MSDN 文档对 COM 驱动程序的功能有误导性,这让 Microsoft 感到尴尬。无论如何,除非大量遗留应用程序突然面临向后兼容性问题,否则无法解决此问题。

关于c - 在 GetCommState 之后 DCB 结构的 fParity 成员始终为 FALSE,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36411498/

10-16 11:11