Win32 API串口通信:如何查询可读取字节数?
Win32串口查询可读取字节数的正确方法
串口不属于普通磁盘文件,GetFileSizeEx()函数仅适用于磁盘文件操作,无法用来查询串口缓冲区的待读取字节数。要实现类似Arduino中Serial.available()的功能,应该使用Win32 API提供的ClearCommError()函数。
核心逻辑
ClearCommError()函数可获取串口的通信错误状态,同时填充COMSTAT结构体,其中的cbInQue字段就是当前串口输入缓冲区中等待读取的字节总数。
修改后的代码示例
替换你原代码中调用GetFileSizeEx()的部分,同时修复空指针导致的异常问题:
#include <Windows.h> #include <iostream> #include <string> int main() { HANDLE hFile; hFile = CreateFile("COM4", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if(hFile == INVALID_HANDLE_VALUE) { std::cout << "bad handle" << std::endl; return 0; } DCB cerialParams = {0}; cerialParams.DCBlength = sizeof(cerialParams); if(!GetCommState(hFile, &cerialParams)) { std::cout << "GetCommState failed" << std::endl; CloseHandle(hFile); return 0; } cerialParams.BaudRate = CBR_9600; cerialParams.ByteSize = 8; cerialParams.StopBits = ONESTOPBIT; cerialParams.Parity = NOPARITY; if(!SetCommState(hFile, &cerialParams)) { std::cout << "SetCommState failed" << std::endl; CloseHandle(hFile); return 0; } COMMTIMEOUTS timeouts = {0}; timeouts.ReadIntervalTimeout = 500; timeouts.ReadTotalTimeoutConstant = 500; timeouts.ReadTotalTimeoutMultiplier = 10; timeouts.WriteTotalTimeoutConstant = 500; timeouts.WriteTotalTimeoutMultiplier = 10; if(!SetCommTimeouts(hFile, &timeouts)) { std::cout << "SetCommTimeouts failed" << std::endl; CloseHandle(hFile); return 0; } // 替换GetFileSizeEx的正确逻辑 DWORD errors; COMSTAT stat; if (ClearCommError(hFile, &errors, &stat)) { std::cout << "当前可读取字节数: " << stat.cbInQue << std::endl; } else { std::cout << "ClearCommError调用失败,错误码: " << GetLastError() << std::endl; } CloseHandle(hFile); return 0; }
关键说明
ClearCommError()会清除当前的通信错误状态,同时返回串口的实时状态COMSTAT结构体的cbInQue字段准确反映了输入缓冲区中未读取的字节数- 你原代码中
PLARGE_INTEGER fSizeStruct{0}是一个空指针,调用GetFileSizeEx()会导致内存访问异常,这也是控制台输出失效的直接原因
内容的提问来源于stack exchange,提问作者crispeeweevile
相关产品推荐
相关产品推荐

