Windows串口枚举实现求助:解决C3861、E0020编译错误
Windows串口枚举与通信问题修复
编译错误原因及修复
1. GetDefaultCommConfig参数错误
错误地将字符串字面量L"buffer"传给函数,而非变量buffer的内容;同时Unicode编译环境下,函数要求宽字符路径,原代码的char数组类型不匹配。修正为使用宽字符数组存储串口路径,并正确传入变量。
2. 成员函数调用错误
COM_exists是SerialPort类的成员函数,不能全局直接调用,需先创建类实例再通过对象调用。
3. cout格式使用错误
cout <<"COM%d \n";是printf语法,cout不支持%d格式符,需改为直接拼接输出。
4. 主函数结构错误
原主函数片段是裸if语句,未包裹在main函数内,且num变量未定义。
5. snprintf兼容性问题
Visual Studio环境下建议使用_snwprintf(宽字符版本)替代snprintf,避免编译兼容性问题。
修正后的完整代码
头文件 SerialPort.h
#pragma once #include <windows.h> #include <iostream> class SerialPort { public: BOOL COM_exists(int port); BOOL Open(int port, DWORD baudRate = CBR_9600); void Close(); BOOL Write(const char* data, DWORD length); BOOL Read(char* buffer, DWORD bufferSize, DWORD& bytesRead); private: HANDLE hSerial = INVALID_HANDLE_VALUE; };
实现文件 SerialPort.cpp
#include "stdafx.h" #include "SerialPort.h" #include <cstring> BOOL SerialPort::COM_exists(int port) { if (!(1 <= port && port <= 255)) { return FALSE; } wchar_t buffer[7]; _snwprintf(buffer, sizeof(buffer)/sizeof(wchar_t), L"COM%d", port); COMMCONFIG CommConfig; DWORD size = sizeof(CommConfig); return (GetDefaultCommConfig(buffer, &CommConfig, &size) || size > sizeof(CommConfig)); } BOOL SerialPort::Open(int port, DWORD baudRate) { wchar_t portPath[7]; _snwprintf(portPath, sizeof(portPath)/sizeof(wchar_t), L"COM%d", port); hSerial = CreateFile(portPath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hSerial == INVALID_HANDLE_VALUE) { return FALSE; } DCB dcbSerialParams = {0}; dcbSerialParams.DCBlength = sizeof(dcbSerialParams); if (!GetCommState(hSerial, &dcbSerialParams)) { Close(); return FALSE; } dcbSerialParams.BaudRate = baudRate; dcbSerialParams.ByteSize = 8; dcbSerialParams.StopBits = ONESTOPBIT; dcbSerialParams.Parity = NOPARITY; if (!SetCommState(hSerial, &dcbSerialParams)) { Close(); return FALSE; } COMMTIMEOUTS timeouts = {0}; timeouts.ReadIntervalTimeout = 50; timeouts.ReadTotalTimeoutConstant = 50; timeouts.ReadTotalTimeoutMultiplier = 10; timeouts.WriteTotalTimeoutConstant = 50; timeouts.WriteTotalTimeoutMultiplier = 10; if (!SetCommTimeouts(hSerial, &timeouts)) { Close(); return FALSE; } return TRUE; } void SerialPort::Close() { if (hSerial != INVALID_HANDLE_VALUE) { CloseHandle(hSerial); hSerial = INVALID_HANDLE_VALUE; } } BOOL SerialPort::Write(const char* data, DWORD length) { DWORD bytesWritten; return WriteFile(hSerial, data, length, &bytesWritten, NULL) && bytesWritten == length; } BOOL SerialPort::Read(char* buffer, DWORD bufferSize, DWORD& bytesRead) { return ReadFile(hSerial, buffer, bufferSize, &bytesRead, NULL); }
主函数文件 main.cpp
#include "stdafx.h" #include <iostream> #include "SerialPort.h" using namespace std; int main() { SerialPort sp; // 枚举可用串口 cout << "可用串口列表:\n"; for (int i = 1; i < 256; ++i) { if (sp.COM_exists(i)) { cout << "COM" << i << "\n"; } } // 选择并连接串口 int selectedPort; cout << "\n请输入要连接的串口编号(如1对应COM1): "; cin >> selectedPort; if (sp.Open(selectedPort)) { cout << "串口COM" << selectedPort << "打开成功\n"; // 发送测试数据 const char* testData = "Hello Serial Port!"; if (sp.Write(testData, strlen(testData))) { cout << "测试数据发送成功\n"; } // 读取串口数据 char readBuffer[1024]; DWORD bytesRead; if (sp.Read(readBuffer, sizeof(readBuffer), bytesRead)) { readBuffer[bytesRead] = '\0'; cout << "收到串口数据: " << readBuffer << "\n"; } sp.Close(); } else { cout << "串口COM" << selectedPort << "打开失败,请检查串口是否存在或被占用\n"; } system("pause"); return 0; }
内容的提问来源于stack exchange,提问作者taek9105
相关产品推荐
相关产品推荐

