news 2026/7/27 3:50:40

当项目不让使用 Qt!如何实现串口通信?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
当项目不让使用 Qt!如何实现串口通信?

在实际工程中,是否使用 Qt往往并不是技术人员单方面能决定的事情。

常见的限制包括:

  • 商业项目对Qt LGPL / 商业授权的顾虑
  • 项目交付形式不允许引入大型框架
  • 甲方或合规部门明确要求禁止使用 Qt
  • 工程本身是纯 C / C++ 工具链,不希望引入额外依赖

在这种背景下,串口通信依然是绕不开的需求。

当项目因版权或授权原因不能使用 Qt 时,如何在 Windows 平台上用纯 C++ 实现稳定的串口通信?


一、为什么不能使用 Qt 会影响串口实现?

Qt 提供了QSerialPort,使用起来非常方便:

  • 自动管理线程
  • 信号槽驱动
  • 跨平台

但它的前提是:

  • 项目已经使用 Qt
  • 授权模型可接受
  • 可以接受引入完整 Qt 运行环境

一旦这些前提不成立,QSerialPort就不再是可选项。

这时,唯一可靠的选择就是:

直接使用 Windows API 提供的串口接口


二、Windows 下串口通信的“官方路径”

在 Windows 系统中,串口本质上是一个设备文件,可以像普通文件一样操作。

核心 API 包括:

  • CreateFile—— 打开串口
  • GetCommState / SetCommState—— 配置串口参数
  • ReadFile / WriteFile—— 数据收发
  • COMMTIMEOUTS—— 读写超时控制

这些接口全部属于Windows SDK,不涉及任何第三方库或授权问题。


三、设计一个可用的纯 C++ 串口程序

在不使用 Qt 的前提下,一个实用的串口程序通常需要解决几个问题:

  1. 如何防止程序一启动就退出
  2. 如何同时进行发送和接收
  3. 如何在没有控制台窗口的情况下输出调试信息

典型做法是:

  • 使用线程分别处理发送和接收
  • 使用WinAPI 事件阻塞主线程
  • 使用OutputDebugString输出调试信息

四、完整示例:纯 C++ / Windows API 串口通信

下面是一份完整、可直接使用的示例代码,实现了:

  • 打开串口
  • 定时发送数据
  • 接收并打印数据
  • 程序长期运行,不依赖 Qt

示例代码

#include<windows.h>#include<thread>#include<atomic>#include<cstdio>std::atomic<bool>running(true);/*************** 打印工具函数 ***************/voiddebugPrint(constchar*fmt,...){charbuf[512];va_list args;va_start(args,fmt);vsnprintf(buf,sizeof(buf),fmt,args);va_end(args);OutputDebugStringA(buf);}/*************** 串口接收线程 ***************/voidserialReadThread(HANDLE hSerial){charbuffer[256];DWORD bytesRead;while(running){if(ReadFile(hSerial,buffer,sizeof(buffer)-1,&bytesRead,NULL)){if(bytesRead>0){buffer[bytesRead]='\0';debugPrint("[RX] %s\n",buffer);}}Sleep(10);}}/*************** 串口发送线程 ***************/voidserialWriteThread(HANDLE hSerial){constchar*msg="Hello Serial\r\n";DWORD bytesWritten;while(running){BOOL ok=WriteFile(hSerial,msg,strlen(msg),&bytesWritten,NULL);if(ok&&bytesWritten>0){debugPrint("[TX] %s",msg);}else{debugPrint("[TX] 发送失败,错误码=%lu\n",GetLastError());}Sleep(1000);}}intmain(){// 打开串口HANDLE hSerial=CreateFile(L"\\\\.\\COM8",// ← 改成你的串口号GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);if(hSerial==INVALID_HANDLE_VALUE){debugPrint("串口打开失败,错误码=%lu\n",GetLastError());return-1;}debugPrint("串口打开成功\n");// 配置串口DCB dcb={0};dcb.DCBlength=sizeof(dcb);GetCommState(hSerial,&dcb);dcb.BaudRate=CBR_9600;dcb.ByteSize=8;dcb.StopBits=ONESTOPBIT;dcb.Parity=NOPARITY;SetCommState(hSerial,&dcb);// 超时COMMTIMEOUTS timeouts={0};timeouts.ReadIntervalTimeout=50;timeouts.ReadTotalTimeoutConstant=50;timeouts.ReadTotalTimeoutMultiplier=10;SetCommTimeouts(hSerial,&timeouts);// 启动线程std::threadtRead(serialReadThread,hSerial);std::threadtWrite(serialWriteThread,hSerial);// 主线程永久阻塞HANDLE hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);WaitForSingleObject(hEvent,INFINITE);running=false;tRead.join();tWrite.join();CloseHandle(hSerial);return0;}

五、这种方式的优缺点

优点

  • 不依赖 Qt,不涉及授权问题
  • 仅使用 Windows 官方 API
  • 可用于任何纯 C++ 工程
  • 行为可控、透明

缺点

  • 代码量明显增加
  • 需要手动管理线程和资源
  • 不具备跨平台能力

六、Qt 仍然有价值,但不是唯一解

授权允许、工程条件合适的情况下,Qt 的QSerialPort依然是非常优秀的选择:

  • 代码简洁
  • 可维护性高
  • 跨平台

但当“不能使用 Qt” 成为硬性条件时,直接使用 Windows API 并不是退而求其次,而是唯一合规且可靠的工程路径

#include <QCoreApplication> #include <QSerialPort> #include <QSerialPortInfo> #include <QTimer> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QSerialPort serial; // 1. 串口参数 serial.setPortName("COM8"); // 串口号 serial.setBaudRate(QSerialPort::Baud9600); serial.setDataBits(QSerialPort::Data8); serial.setStopBits(QSerialPort::OneStop); serial.setParity(QSerialPort::NoParity); serial.setFlowControl(QSerialPort::NoFlowControl); // 2. 打开串口 if (!serial.open(QIODevice::ReadWrite)) { qDebug() << "串口打开失败:" << serial.errorString(); return -1; } qDebug() << "串口打开成功"; // 3. 接收数据(信号槽) QObject::connect(&serial, &QSerialPort::readyRead, [&]() { QByteArray data = serial.readAll(); qDebug() << "[RX]" << data; }); // 4. 定时发送 QTimer timer; QObject::connect(&timer, &QTimer::timeout, [&]() { QByteArray msg = "Hello Serial"; serial.write(msg); qDebug() << "[TX]" << msg; }); timer.start(1000); // 1 秒发送一次 return a.exec(); }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/25 4:52:31

API接口调用操作步骤与公众号内容热度解析指南

公众号内容热度分析的重要性‌ 在数字化时代&#xff0c;公众号内容的热度直接影响用户粘性和传播效果。对于软件测试从业者&#xff0c;掌握API接口调用技术不仅能获取实时数据&#xff0c;还能通过自动化测试验证数据准确性&#xff0c;优化内容策略。本文将分步解析API操作…

作者头像 李华
网站建设 2026/7/24 3:06:59

<span class=“js_title_inner“>阿里开源的一款数据同步工具 DataX,稳定又高效,嘎嘎好用!</span>

前言我们公司有个项目的数据量高达五千万&#xff0c;但是因为报表那块数据不太准确&#xff0c;业务库和报表库又是跨库操作&#xff0c;所以并不能使用 SQL 来进行同步。当时的打算是通过 mysqldump 或者存储的方式来进行同步&#xff0c;但是尝试后发现这些方案都不切实际&a…

作者头像 李华
网站建设 2026/7/24 18:37:53

救命神器9个降AIGC工具 千笔帮你快速降AI率

AI降重工具&#xff1a;让论文更自然&#xff0c;更安心 在当前学术写作中&#xff0c;越来越多的高校开始采用AIGC检测系统来评估论文的原创性。对于本科生而言&#xff0c;一篇由AI生成的论文&#xff0c;虽然内容完整、逻辑清晰&#xff0c;但往往因“AI痕迹”过重而被判定…

作者头像 李华
网站建设 2026/7/23 13:33:48

【小程序毕设全套源码+文档】基于微信小程序的同城钓鱼社交APP设计与实现(丰富项目+远程调试+讲解+定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/7/22 14:54:26

掌握XSS手动测试:软件测试从业者必备技能

XSS手动测试的必要性与挑战‌ 跨站脚本攻击&#xff08;XSS&#xff09;是Web应用安全的头号威胁之一&#xff0c;能在用户浏览器中执行恶意脚本&#xff0c;导致数据泄露或会话劫持。对于软件测试从业者&#xff0c;手动测试是识别XSS漏洞的关键手段&#xff0c;尤其在自动化…

作者头像 李华