ReadFile() 说失败,但错误代码是 ERROR_SUCCESS

发布于 2024-11-01 13:55:01 字数 2167 浏览 5 评论 0原文

我在 Windows 上使用 ReadFile() 从串行端口读取数据。这段代码在某个时间点工作得很好,但现在失败了,我正在尝试找出问题的根源,所以我怀疑这是串行配置或超时的问题,因为这些都没有改变。

ReadFile() 返回 false,表示发生错误。但是,当我立即检查 GetLastError() 的值时,它返回 0,即 ERROR_SUCCESS。读取的字节数为 0,因此我倾向于认为确实出了问题,但该错误代码完全没有用。

有什么想法吗?谢谢。

编辑:以下是一些相关的代码片段:

#define GPS_COM_PORT L"COM3"

// for reference, the device communicates at 115200 baud,
// no parity, 1 stop bit, no flow control

// open gps com port
hGpsUart = CreateFile(GPS_COM_PORT, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hGpsUart == INVALID_HANDLE_VALUE)
{
    if (GetLastError() == ERROR_FILE_NOT_FOUND)
    {
        msg.setText("GPS COM port does not exist!");
        msg.exec();
        QApplication::quit();
    }

    msg.setText("Error occurred while trying to open GPS COM port!");
    msg.exec();
    QApplication::quit();
}

// set gps com port settings
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
if (!GetCommState(hGpsUart, &dcbSerialParams))
{
    msg.setText("Could not get GPS COM port settings!");
    msg.exec();
    QApplication::quit();
}
dcbSerialParams.BaudRate = CBR_115200;
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
if (!SetCommState(hGpsUart, &dcbSerialParams))
{
    msg.setText("Could not set GPS COM port settings!");
    msg.exec();
    QApplication::quit();
}

// set gps com port timeouts
timeouts.ReadIntervalTimeout = MAXDWORD;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 50;
timeouts.WriteTotalTimeoutMultiplier = 10;
if (!SetCommTimeouts(hGpsUart, &timeouts))
{
    msg.setText("Could not set GPS COM port timeouts!");
    msg.exec();
    QApplication::quit();
}

// ... later in the code ...

char buf[161] = {0};
DWORD bytes_read = 0;

// This returns false...
if (!ReadFile(hGpsUart, buf, 160, &bytes_read, NULL)) 
{
    // Yet in here, GetLastError() returns ERROR_SUCCESS (0)
    QMessageBox msg;
    msg.setText("Error reading from GPS UART!");
    msg.exec();
}

I'm using ReadFile() on Windows to read data from a serial port. This code was working fine at one point in time, but it's now failing and I'm trying to track down the source of the problem, so I doubt it's a problem with the serial configuration or timeouts, since none of that has changed.

ReadFile() returns false, indicating that an error occurred. However, when I immediately check the value of GetLastError(), it returns 0, which is ERROR_SUCCESS. The number of bytes read is 0, so I'm inclined to think that indeed something has gone wrong, but that error code is utterly useless.

Any ideas? Thanks.

EDIT: Here are some relevant code snippets:

#define GPS_COM_PORT L"COM3"

// for reference, the device communicates at 115200 baud,
// no parity, 1 stop bit, no flow control

// open gps com port
hGpsUart = CreateFile(GPS_COM_PORT, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hGpsUart == INVALID_HANDLE_VALUE)
{
    if (GetLastError() == ERROR_FILE_NOT_FOUND)
    {
        msg.setText("GPS COM port does not exist!");
        msg.exec();
        QApplication::quit();
    }

    msg.setText("Error occurred while trying to open GPS COM port!");
    msg.exec();
    QApplication::quit();
}

// set gps com port settings
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
if (!GetCommState(hGpsUart, &dcbSerialParams))
{
    msg.setText("Could not get GPS COM port settings!");
    msg.exec();
    QApplication::quit();
}
dcbSerialParams.BaudRate = CBR_115200;
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
if (!SetCommState(hGpsUart, &dcbSerialParams))
{
    msg.setText("Could not set GPS COM port settings!");
    msg.exec();
    QApplication::quit();
}

// set gps com port timeouts
timeouts.ReadIntervalTimeout = MAXDWORD;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 50;
timeouts.WriteTotalTimeoutMultiplier = 10;
if (!SetCommTimeouts(hGpsUart, &timeouts))
{
    msg.setText("Could not set GPS COM port timeouts!");
    msg.exec();
    QApplication::quit();
}

// ... later in the code ...

char buf[161] = {0};
DWORD bytes_read = 0;

// This returns false...
if (!ReadFile(hGpsUart, buf, 160, &bytes_read, NULL)) 
{
    // Yet in here, GetLastError() returns ERROR_SUCCESS (0)
    QMessageBox msg;
    msg.setText("Error reading from GPS UART!");
    msg.exec();
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

七色彩虹 2024-11-08 13:55:01

我认为您观察的关键是源代码中的短语“但是在这里,GetLastError() 返回 ERROR_SUCCESS (0)”

对 GetLastError 的调用必须是(大概)失败调用之后进行的下一个 Win32 调用。作为实验,尝试在失败处理程序中显式调用 GetLastError(),但在消息框调用之前。我怀疑您会看到真正的故障代码。

祝你好运!

I think the key to your observations is the phrase in your source that says "Yet in here, GetLastError() returns ERROR_SUCCESS (0)"

The call to GetLastError has to be the very next Win32 call made after the (presumably) failing call. As an experiment, try putting an explicit call to GetLastError() within your failure handler, but just before the message box call. I suspect you'll see the true failure code.

Good luck!

羅雙樹 2024-11-08 13:55:01

QMessageBox 的构造函数可能正在执行清除“GetLastError”的操作。试试这个:

if (!ReadFile(hGpsUart, buf, 160, &bytes_read, NULL)) 
{
    int LastError = GetLastError() ;
    QMessageBox msg;
    msg.setText(QString("Error %1 reading from GPS UART!").arg(LastError));
    msg.exec();
}

The constructor of QMessageBox may be doing something that clears `GetLastError'. Try this:

if (!ReadFile(hGpsUart, buf, 160, &bytes_read, NULL)) 
{
    int LastError = GetLastError() ;
    QMessageBox msg;
    msg.setText(QString("Error %1 reading from GPS UART!").arg(LastError));
    msg.exec();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文