读取文件在多次串行端口读取后ERROR_INVALID_HANDLE
ReadFile ERROR_INVALID_HANDLE after several Serial Port reads
我是Windows上的串行库的新手,因此非常感谢任何指导。我有一个插入USB端口的微控制器,它不断地通过UART发送数据。应该接收的内容的一个例子是:
ADC 值 1:848 ADC 值 2:972 ADC 中断计数:2300
(暂停)
ADC 值 1:849 ADC 值 2:971 ADC 中断数:2301
程序本身在GUI上有一个线程,一旦用户选择了COM端口,就会创建一个句柄名称为hCom的文件。创建一个新线程并将hCom传递给它。我尝试在新线程上使用无限 while 循环来不断读取端口(稍后我将实现适当的检查条件)。ReadFile 函数一次读取一个字节并将它们打印到屏幕上。这种连续的循环。但是,在发送第一组(val 1、val 2、int count)后,不会再收到任何数据。
文件和线程生成的创建在这里:
HANDLE hCom = CreateFile(szComPort,
GENERIC_READ |
GENERIC_WRITE, // desired access should be read&write
0, // COM port must be opened in non-sharing mode
NULL, // don't care about the security
OPEN_EXISTING, // IMPORTANT: must use OPEN_EXISTING for a COM port
0, // usually overlapped but non-overlapped for existance test
NULL);
if (INVALID_HANDLE_VALUE == hCom) {
MessageBox(hwnd, "This port is not available or is in use.", "Error", MB_OK | MB_ICONERROR);
return WndProc(hwnd, WM_CREATE, wParam, lParam);
}
AppendText(hOut, "CONNECTED TO " + std::string(szComPort) + "rn");
DWORD myThreadID;
CreateThread(NULL, 0, serialHandler, &hCom, 0, &myThreadID);
return WndProc(hwnd, WM_CREATE, wParam, lParam);
这是我的线程处理程序:
DWORD WINAPI serialHandler(LPVOID lpParameter) {
HANDLE &hCom = *((HANDLE *) lpParameter);
SetCommState(hCom, &dcbSerialParams);
COMMTIMEOUTS tMyTimeOuts = {
MAXDWORD, // DWORD ReadIntervalTimeout;
0, // DWORD ReadTotalTimeoutMultiplier;
10000, // DWORD ReadTotalTimeoutConstant;
1000, // DWORD WriteTotalTimeoutMultiplier;
1000, // DWORD WriteTotalTimeoutConstant;
};
if (!SetCommTimeouts(hCom, &tMyTimeOuts))
printf("setting port time-outs.");
std::string sb = "";
DWORD dwEventMask, dwSize = 0;
while (1) {
char szBuf;
DWORD dwIncommingReadSize;
do {
int error = ReadFile(hCom, &szBuf, 1, &dwIncommingReadSize, NULL);
if (error !=0) {
if (dwIncommingReadSize > 0) {
dwSize += dwIncommingReadSize;
sb += szBuf;
printf("%c", szBuf);
sb = "";
}
} else {
printf("No Data Received - ");
DWORD lasterror = GetLastError();
lasterror = GetLastError();
}
} while (dwIncommingReadSize > 0);
}
return 0;
}
编辑:这是导致我出现问题的WM_CREATE的一部分
hCom = CreateFile(szComPort,
GENERIC_READ | GENERIC_WRITE, // desired access should be read&write
0, // COM port must be opened in non-sharing mode
NULL, // don't care about the security
OPEN_EXISTING, // IMPORTANT: must use OPEN_EXISTING for a COM port
0, // usually overlapped but non-overlapped for existance test
NULL); // always NULL for a general purpose COM port
if (INVALID_HANDLE_VALUE == hCom) {
if ((ERROR_ACCESS_DENIED) == GetLastError()) { // then it exists and currently opened
wsprintf(szComPort, _T("&COM%d (in use)"), i);
AppendMenu(hSubMenu, MF_STRING, COM_PORT_MESSAGE_BASE + i, szComPort);
}
} else { // COM port exists
wsprintf(szComPort, _T("COM%d"), i);
AppendMenu(hSubMenu, MF_STRING, COM_PORT_MESSAGE_BASE + i, szComPort);
CloseHandle(hCom);
}
实际输出为:
ADC 值 1: 848 ADC 值 2:972 ADC 中断数:2879 A收到的数据
- 未收到数据 - 未收到数据 -等等。串行处理程序中的变量 lasterror 返回 6,即ERROR_INVALID_HANDLE。我不确定为什么句柄在一次"设置"读取后从有效变为无效。
我在代码的另一部分打开了文件句柄,但忘记关闭它。当我尝试打开端口时,这导致了问题,它不再存在,并且我的 readfile 功能不起作用。确保检查所有创建文件的实例。
具体来说,我的代码不起作用的原因有两个。首先,我将 hCom 的本地副本传递到另一个线程的堆栈上。
CreateThread(NULL, 0, serialHandler, &hCom, 0, &myThreadID);
然后我返回到相同的功能以重新绘制 GUI(我想更新我的菜单栏以显示已建立连接)。
return WndProc(hwnd, WM_CREATE, wParam, lParam);
WM_CREATE内部是端口扫描,它会重新打开所有端口以检查它们是否打开。
hCom = CreateFile(szComPort,
GENERIC_READ | GENERIC_WRITE, // desired access should be read&write
0, // COM port must be opened in non-sharing mode
NULL, // don't care about the security
OPEN_EXISTING, // IMPORTANT: must use OPEN_EXISTING for a COM port
0, // usually overlapped but non-overlapped for existance test
NULL); // always NULL for a general purpose COM port
这会干扰早期的线程,因为它使用相同的句柄来收集数据。这就是为什么它会工作一段时间,直到另一个线程运行并重用 COM 端口。我通过删除 return 函数、将整数传递给新线程并在新线程中打开 COM 端口来解决此问题。
- 理解boost::asio-async_read在无需读取内容时的行为
- "error: no matching function for call to"构造函数错误
- 使用新行和不使用新行读取文件
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 读取文件并输入到矢量中
- 用c++从输入文件中读取另一行
- 读取文件的最后一行并输入到链接列表时出错
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 无法找到/读取配置文件.conf-FileIOException
- 如何使用Luacneneneba API正确读取字符串和表参数
- C++将文本文件中的数据读取到结构数组中
- 正在将csv文件读取为双精度矢量
- 为什么 sscanf 无法从一个字符串中读取uint64_t和字符?
- 使用 LuaBridge 将 LuaJIT 绑定到C++会导致"PANIC: unprotected error"
- 为什么在读取文件大小时文件IO速度会发生变化
- 正在读取二进制文件(is_open)
- 如何在c++中从文本文件中逐行读取整数
- SSH通过/sbin/SSH无法读取RSA密钥文件(从控制台运行)
- 独立读取-修改-写入顺序
- MySQL Error 2006: MySQL server has gone away(读取通信包出错)