You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 00:05:23