DCB 结构的 fParity 成员在 GetCommState 之后始终为 FALSE
fParity member of DCB structure always FALSE after a GetCommState
含着血泪,我才发现每次调用 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 很尴尬。无论如何,除非大量遗留应用程序突然面临向后兼容性问题,否则无法解决此问题。
从上面的代码看来,您正在使用标记和 space 奇偶校验方案进行通信。当您调用 GetCommState
时,您在 Parity
字段中得到了什么。
因为 GetCommState
没有返回 fParity
作为 True
,它可能有助于调用 ClearCommError
并检查第二个输出参数 COMSTAT
是否有 CE_RXPARITY
.不确定你的情况是否有效,但在端口上收到一些数据后调用 ClearCommError
时,它应该有效。
含着血泪,我才发现每次调用 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 很尴尬。无论如何,除非大量遗留应用程序突然面临向后兼容性问题,否则无法解决此问题。
从上面的代码看来,您正在使用标记和 space 奇偶校验方案进行通信。当您调用 GetCommState
时,您在 Parity
字段中得到了什么。
因为 GetCommState
没有返回 fParity
作为 True
,它可能有助于调用 ClearCommError
并检查第二个输出参数 COMSTAT
是否有 CE_RXPARITY
.不确定你的情况是否有效,但在端口上收到一些数据后调用 ClearCommError
时,它应该有效。