【Qt开发】建立自己的Qt基本类、函数库封装 包括图表、多线程、串口等

news2024/9/26 5:18:10

【Qt开发】建立自己的Qt基本类、函数库 包括图表、多线程、串口等

文章目录

  • 前言
  • QtCharts绘图
  • 继承QObject的QThread多线程
  • QSerialPort串口配置、发送、接收回调函数
  • 附录:C语言到C++的入门知识点(主要适用于C语言精通到Qt的C++开发入门)
    • C语言与C++的不同
    • C++中写C语言代码
    • C语言到C++的知识点
    • Qt开发中需要了解的C++基础知识
      • namespace
      • 输入输出
      • 字符串类型
      • class类
        • 构造函数和析构函数(解析函数)
        • 类的继承

前言

为了使开发更方便 对使用到的模块进行了总结 最终封装成了一个类、函数库
使用typedef、class类、回调函数等来建立 方便打包和开发

开源地址:
gitee地址

QtCharts绘图

【Qt开发】QtCharts图表 在ui上添加QChartView控件并进行绘图配置
可以实现一键配置

#ifndef MY_QT_DEF_H
#define MY_QT_DEF_H
#include <QValueAxis>
#include <QList>
#include <QSplineSeries>
#include <QString>
#include <QChart>
#include <QChartView>
QT_CHARTS_USE_NAMESPACE

typedef struct
{
    float min;
    float max;

    QString tittle;
    QString format;
    Qt::Alignment alignment;

    QValueAxis *axis;
}MY_QChartView_Float_Axis_Struct;

//splineSeries曲线实例化(折线用QLineSeries)
typedef struct
{
    int maxSize;
    QList<float> data;
    QString tittle;

    MY_QChartView_Float_Axis_Struct X;
    MY_QChartView_Float_Axis_Struct Y;

    QPainter::RenderHint renderHint;
    //上面是必配置的参数 下面是指针类型
    QSplineSeries *splineSeries;

    QChart *chart;
    QChartView *chartView;
}MY_QChartView_Float_Struct;

void Init_MY_QChartView_Float_Axis_Struct(MY_QChartView_Float_Axis_Struct *Stu,QChart *chart);
void Init_MY_QChartView_Float_Struct(MY_QChartView_Float_Struct *Stu);
void Add_MY_QChartView_Float_Value(MY_QChartView_Float_Struct *Stu,float value);

#endif // MY_QT_DEF_H


#include "MY_QT_DEF.h"

void Init_MY_QChartView_Float_Axis_Struct(MY_QChartView_Float_Axis_Struct *Stu,QChart *chart)
{
    Stu->axis->setLabelFormat(Stu->format);
    Stu->axis->setTitleText(Stu->tittle);
    chart->addAxis(Stu->axis, Stu->alignment);
    Stu->axis->setRange(Stu->min,Stu->max);
}

void Init_MY_QChartView_Float_Struct(MY_QChartView_Float_Struct *Stu)
{
    Stu->chart=new QChart();
    Stu->splineSeries = new QSplineSeries();
    Stu->X.axis=new QValueAxis();
    Stu->Y.axis=new QValueAxis();

    Stu->chart->legend()->hide();
    Stu->chart->setTitle(Stu->tittle);
    Stu->chart->addSeries(Stu->splineSeries);

    Init_MY_QChartView_Float_Axis_Struct(&Stu->X,Stu->chart);
    Init_MY_QChartView_Float_Axis_Struct(&Stu->Y,Stu->chart);

    Stu->splineSeries->attachAxis(Stu->X.axis);
    Stu->splineSeries->attachAxis(Stu->Y.axis);

    Stu->chartView->setChart(Stu->chart);
    Stu->chartView->setRenderHint(Stu->renderHint);
}

//添加数据自动移动函数
void Add_MY_QChartView_Float_Value(MY_QChartView_Float_Struct *Stu,float value)
{
    Stu->data.append(value);
    while (Stu->data.size() > Stu->maxSize)
    {
        Stu->data.removeFirst();
    }

    Stu->splineSeries->clear();

    float xSpace = (Stu->X.max-Stu->X.min) / (Stu->maxSize - 1);

    for (int i = 0; i < Stu->data.size(); ++i)
    {
        Stu->splineSeries->append(xSpace * i, Stu->data.at(i));
    }
}


继承QObject的QThread多线程

采用moveToThread方法执行多线程
对整体进行了封装
可以自我调用
可以通过注册回调函数来进行不同的工作
【Qt开发】多线程QThread(通过QObject::moveToThread)和QMutex互斥锁的配置和多线程类的封装及回调函数

//QObject的多线程示例
class MY_Thread_Worker;
class MY_Thread_Worker : public QObject
{
    Q_OBJECT
private:
    QMutex lock;
    bool isCanRun;
    bool isCanStart;
    MY_QT_CALLBACK pfCallback;
public slots:
    void Judg_doWork(void)
    {
        this->isCanRun=true;
        //执行
        while(this->isCanRun)
        {
            QMutexLocker locker(&this->lock);
            pfCallback(this,0,NULL);
        }
        isCanStart=true;
    }

signals:
    void startWork(void);
public:
    void * pArg;
    QThread *workerThread;

    void stopWork(bool Wait_Flag)
    {
        this->isCanRun = false;
        if(Wait_Flag)
        {
            QMutexLocker locker(&this->lock);
        }
    }

    bool startThread(void)
    {
        if(!isCanRun && isCanStart)
        {
            isCanStart=false;
            workerThread->start();
            emit this->startWork();
            return true;
        }
        return false;
    }

    bool stopThread(bool Wait_Flag)
    {
        if(workerThread->isRunning())
        {
            stopWork(Wait_Flag);
            return true;
        }
        return false;
    }

    void closeThread(void)
    {
        stopThread(false);
        this->workerThread->quit();
    }

    MY_Thread_Worker(MY_QT_CALLBACK const pfunc,QThread * worker_Thread = nullptr)
    {
        pfCallback=pfunc;
        pArg=nullptr;
        if(!worker_Thread)
        {
            this->workerThread = new QThread;
        }
        else
        {
            this->workerThread = worker_Thread;
        }
        this->moveToThread(workerThread);
        this->stopWork(false);
        isCanStart=true;
        connect(workerThread, SIGNAL(finished()),this, SLOT(deleteLater()));
        connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater()));
        connect(this, SIGNAL(startWork()), this, SLOT(Judg_doWork()));
        // connect(this, SIGNAL(startWork(QString)), worker, SLOT(Judg_doWork(QString)));  主窗口发送函数
        // connect(worker, SIGNAL(resultReady(QString)),this, SLOT(handleResults(QString)));  主窗口接收函数
    }

    ~MY_Thread_Worker()
    {
        closeThread();
    }
};


QSerialPort串口配置、发送、接收回调函数

包装的类具有 单线程/多线程 回调函数/虚函数四种配置方案
同样采用回调函数方便配置和修改
【Qt开发】QSerialPort串口配置、发送、接收回调函数 多线程接收的串口类封装

class MY_SerialPort_Thread;
class MY_SerialPort_Thread : public QObject
{
    Q_OBJECT
private:
    QMutex lock;
    bool isCanRun;
    bool isCanStart;
    bool Thread_Flag;

    MY_QT_CALLBACK pfCallback;
public slots:
    void SerialPort_RX(void)
    {
        SerialPort_RX_Ready_Callback(this);
    }

    void Callback_SerialPort_RX(void)
    {
        pfCallback(this,0,NULL);
    }

    void RX_Thread(void)
    {
        this->isCanRun=true;
        //执行
        while(isCanRun)
        {
            QMutexLocker locker(&this->lock);
            if(SerialPort.waitForReadyRead(1))
            {
                SerialPort_RX_Thread_Callback(this);
            }
        }
        isCanStart=true;
    }

    void Callback_RX_Thread(void)
    {
        this->isCanRun=true;
        //执行
        while(isCanRun)
        {
            QMutexLocker locker(&this->lock);
            if(SerialPort.waitForReadyRead(1))
            {
                pfCallback(this,1,NULL);
            }
        }
        isCanStart=true;
    }

signals:
    void Start_RX_Thread(void);

public:
    QSerialPort SerialPort;
    QList<QString> SerialPort_List;
    QString SerialPort_Name;
    uint32_t BaudRate;
    uint8_t DataBits;
    uint8_t StopBits;
    QSerialPort::Parity Parity;
    QSerialPort::FlowControl FlowControl;

    bool Open_Flag;
    uint8_t RX_Data;
    uint8_t *RX_Buf;
    uint32_t RX_Buf_Size;
    uint32_t RX_Flag;

    QThread workerThread;

    void Stop_Port(uint8_t TX_RX_All)
    {
        switch(TX_RX_All)
        {
            case 0:SerialPort.clear(QSerialPort::Output);break;
            case 1:SerialPort.clear(QSerialPort::Input);break;
            default:SerialPort.clear();SerialPort.flush();break;
        }
    }

    void Scan_SerialPort(void)
    {
        SerialPort_List.clear();
        foreach (const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
        {
            SerialPort_List.append(info.portName());
        }
    }

    void Clean_RX(void)
    {
        RX_Flag=0;
        RX_Data=0;
        memset(RX_Buf,0,RX_Buf_Size);
    }

    void Reset_SerialPort(void)
    {
        Scan_SerialPort();
        BaudRate=115200;
        DataBits=8;
        StopBits=1;
        Parity=QSerialPort::NoParity;
        FlowControl = QSerialPort::NoFlowControl;
        if(Open_Flag)
        {
            Stop_Port(2);
        }
        Clean_RX();
    }

    bool Ctrl_SerialPort(bool OpenNotClose)
    {
        if(OpenNotClose)
        {

            SerialPort.setPortName(SerialPort_Name);
            SerialPort.setBaudRate(BaudRate);
            SerialPort.setFlowControl(FlowControl);

            switch(DataBits)
            {
            case 5:SerialPort.setDataBits(QSerialPort::Data5);break;
            case 6:SerialPort.setDataBits(QSerialPort::Data6);break;
            case 7:SerialPort.setDataBits(QSerialPort::Data7);break;
            case 8:SerialPort.setDataBits(QSerialPort::Data8);break;
            default:break;
            }

            SerialPort.setParity(Parity);

            switch(StopBits)
            {
            case 1:SerialPort.setStopBits(QSerialPort::OneStop);break;
            case 2:SerialPort.setStopBits(QSerialPort::TwoStop);break;
            case 3:SerialPort.setStopBits(QSerialPort::OneAndHalfStop);break;
            default:break;
            }

            if (!SerialPort.open(QIODevice::ReadWrite))
            {
                return false;
            }
            Open_Flag=true;
            if(this->Thread_Flag)
            {
                startThread();
            }
            return true;
        }

        stopThread(true);
        Open_Flag=false;
        SerialPort.close();        
        return true;
    }

    uint32_t SerialPort_TX_Sequence(uint8_t *buf,uint32_t size)
    {
        if(Open_Flag)
        {
            return SerialPort.write((char *)buf,size);
        }
        return 0;
    }

    uint32_t SerialPort_TX(uint8_t *buf,uint32_t size)
    {
        if(Open_Flag)
        {
            SerialPort.clear(QSerialPort::Output);
            return SerialPort.write((char *)buf,size);
        }
        return 0;
    }

    virtual void SerialPort_RX_Ready_Callback(MY_SerialPort_Thread *port)
    {
        Q_UNUSED(port);
        foreach (const uint8_t i,port->SerialPort.readAll())
        {
            port->RX_Data=i;
            SerialPort_RX_Callback(port);
        }
    }

    virtual void SerialPort_RX_Thread_Callback(MY_SerialPort_Thread *port)
    {
        Q_UNUSED(port);
        foreach (const uint8_t i,port->SerialPort.readAll())
        {
            port->RX_Data=i;
            SerialPort_RX_Callback(port);
        }
    }

    virtual void SerialPort_RX_Callback(MY_SerialPort_Thread *port)
    {
        Q_UNUSED(port);
        qDebug()<<port->RX_Data;
    }

    void stopWork(bool Wait_Flag)
    {
        this->isCanRun = false;
        if(Wait_Flag)
        {
            QMutexLocker locker(&this->lock);
        }
    }

    bool startThread(void)
    {
        if(!isCanRun && isCanStart)
        {
            isCanStart=false;
            workerThread.start();
            emit this->Start_RX_Thread();
            return true;
        }
        return false;
    }

    bool stopThread(bool Wait_Flag)
    {
        if(workerThread.isRunning())
        {
            stopWork(Wait_Flag);
            return true;
        }
        return false;
    }

    void closeThread(void)
    {
        stopThread(false);
        this->workerThread.quit();
    }

    MY_SerialPort_Thread(uint32_t Buf_Size=256,bool ThreadNotNormal=false,MY_QT_CALLBACK const pfunc=nullptr)
    {
        pfCallback=pfunc;
        SerialPort_Name="";
        Open_Flag=false;
        RX_Buf_Size = Buf_Size;
        RX_Buf = new uint8_t[RX_Buf_Size];
        SerialPort.setReadBufferSize(RX_Buf_Size);
        this->Thread_Flag = ThreadNotNormal;
        Reset_SerialPort();
        if(Thread_Flag)
        {
            this->moveToThread(&workerThread);
            this->stopWork(false);
            isCanStart=true;
            connect(&workerThread, SIGNAL(finished()),this, SLOT(deleteLater()));
            connect(&workerThread, SIGNAL(finished()), &workerThread, SLOT(deleteLater()));
            if(pfCallback)
            {
                connect(this, SIGNAL(Start_RX_Thread()), this, SLOT(Callback_RX_Thread()));
            }
            else
            {
                connect(this, SIGNAL(Start_RX_Thread()), this, SLOT(RX_Thread()));
            }
        }
        else
        {            
            if(pfCallback)
            {
                connect(&this->SerialPort, SIGNAL(readyRead()),this, SLOT(Callback_SerialPort_RX()));
            }
            else
            {
                connect(&this->SerialPort, SIGNAL(readyRead()),this, SLOT(SerialPort_RX()));
            }
        }
    }

    ~MY_SerialPort_Thread()
    {
        Open_Flag=false;
        SerialPort.close();
        delete RX_Buf;
        closeThread();
    }
};


附录:C语言到C++的入门知识点(主要适用于C语言精通到Qt的C++开发入门)

C语言与C++的不同

C语言是一门主要是面向工程的语言
C++则是面向对象

C语言中 某些功能实现起来较为繁琐
比如结构体定义:

一般写作:

typedef struct stu_A
{
}A;

也可以写作:

typedef struct 
{
}A;

但 大括号后面的名称是不可省去的

不过 C++的写法就比较简单
除了支持上述写法外

也支持直接声明

typedef struct A
{
}

另外 C++是完全支持C语言库和语法的
不过C++里面的库也有些很方便的高级功能用法 只不过实现起来可能不如C的速度快

再者 C语言与C++的编译流程不一样
C语言没有函数重载 所以给编译器传参就是直接传函数名称
但是C++除了传函数名称外 还会穿函数的参数、类型等等 以实现函数重载

C++中写C语言代码

上文提到 C++可以完全兼容C的写法
但是编译流程也还是不一样
所以如果在编译层面进行C语言代码编译 则通常用以下方法:

extern "C"
{
...
}

表面大括号内的内容用C的方法进行编译

另外 如果还是用C++的编译器 但要实现C语言函数 则需要用到C语言的库

在C语言中 我们一般用如下方法导入库

#include <stdio.h>

此方法同样适用于C++ 但是C++可以更方便的写成去掉.h的方式
比如:

#include <iostream>

在C++中 为了调用C语言的库 可以采用在原库名称前加一个"c"的方式导入
如:

#include <cstdio>

这样就可以使用printf等函数了 甚至比C++的std方法更快

C语言到C++的知识点

在这里插入图片描述

Qt开发中需要了解的C++基础知识

namespace

C++面向对象的特性下诞生的一个名称
表示某个函数、变量在某个集合下 用作namespace
比如 <iostream>库中的关键字cin在std下 则写作std::cin
std就是namespace
::表示某空间下的某某
前面是空间名称 后面是变量、函数名称

using namespace可以告诉编译器以下都用xx名称空间
比如:

using namespace std;
cout<<"a";

如果没有告诉编译器所使用的空间名称 则要写成:

std::cout<<"a";

同样 可以自定义某一段代码属于哪个空间:

namespace xx
{
...
}

输入输出

在C++中 用iostream作为输入输出流的库

#include <iostream>

用cin和cout关键字进行输入和输出
如:

using namespace std;
int a=0;
cin>>a; //输入到a

cout<<a;  //输出a

类比scanf和printf
同样 还有一个关键字endl表示换行
cout和cin的传参是不固定的
由编译器自行裁定

字符串类型

在C语言中 常用char *表示字符串
但是在C++中 可以直接用string类型
比如:

char * s="456";
string str="123";

由于cout的特性 这两种字符串都可以直接打印
但如果使用C语言中printf的打印方式时 采用%s方式打印字符串 则不能传入string类型

class类

C++的核心就是class
同Python等支持面向对象的语言一样
可以理解成一个支持函数、继承、自动初始化、销毁的结构体
在class类中 有private私有、public公有变量
前者只能内部访问 后者可以外部调用使用
如:

class A
{
public:
int a;
private:
int b;
}

a可以用A.a的方式方位 b则外部无法访问

构造函数和析构函数(解析函数)

构造函数可以理解成对类的初始化 反之析构函数则是退出时进行销毁前的函数
两者需要与类的名称相同 析构函数则在前面加一个~表示非
如:

class A
{
public:
int a;
A();
~A();
private:
int b;
}

A::A()
{
...
}

A::~A()
{
...
}

构造函数可以定义传参 析构函数则不行

类的继承

如果有两个类A和B 想让A里面包含B 则可以写作继承的写法
继承后 A类的变量可以直接调用B下面的成员
如:

class B
{
int b;
}
class A: public B
{
int a;
}

在定义A后 可以访问到B的成员b 当然 继承也可以私有

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2067369.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024年企业记账最主流的8大财务软件大对比

企业记账的8大主流财务软件&#xff1a;1.合思&#xff1b;2.用友好会计财务软件&#xff1b;3.浪潮云会计&#xff1b;4.金蝶精斗云财务软件&#xff1b;5.Zoho Books&#xff1b;6.管家婆&#xff1b;7.QuickBooks&#xff1b;8.云账房。 对小企业主来说&#xff0c;采用高效…

Linux | 探究C语言文件接口与Linux系统文件接口的区别与联系 | fopen和open的区别与联系

什么是尘土&#xff1f;从大地之肺发出的一声叹息。 - 《阿多尼斯诗集》(阿多尼斯) 2024.8.23 目录 1、C语言IO接口 示例代码&#xff1a;使用 fopen 和 fclose 读写文件 示例1&#xff1a;通过write写文件 示例2&#xff1a;通过read写文件 C语言的标准流&#xff1a;std…

集合及数据结构第十节(上)————优先级队列,堆的创建、插入、删除与用堆模拟实现优先级队列

系列文章目录 集合及数据结构第十节&#xff08;上&#xff09;————优先级队列&#xff0c;堆的创建、插入、删除与用堆模拟实现优先级队列 优先级队列&#xff0c;堆的创建、插入、删除与用堆模拟实现优先级队列 优先级队列的概念堆的概念堆的存储方式堆的创建变量的作…

谷粒商城实战笔记-250-商城业务-消息队列-RabbitMQ安装-Docker

一&#xff0c;docker安装RabbitMq RabbitMQ 是一个开源的消息代理软件&#xff0c;广泛用于实现异步通信和应用程序解耦。 使用 Docker 容器化技术可以简化 RabbitMQ 的安装和部署过程。 以下是使用 Docker 安装 RabbitMQ 的详细步骤。 步骤 1: 安装 Docker 如果您的系统…

Linux 软件编程 网络 tcp

1.TCP粘包问题&#xff1a; TCP发送数据是连续的&#xff0c;两次发送的数据可能粘连成一包被接收到 1.解决粘包问题方法&#xff1a; 1.接收指定长度&#xff1a;&#xff08;不稳定&#xff09; 发送5个字节 接收5个字节 2.睡眠&#x…

【数据库】Mysql 批量变更所有字段类型为varchar的字符集

生成变更语句 SELECT CONCAT(ALTER TABLE , TABLE_NAME, MODIFY , COLUMN_NAME, , COLUMN_TYPE, , CHARACTER SET utf8 COLLATE utf8_general_ci , CASE WHEN IS_NULLABLE YES THEN NULL DEFAULT NULL WHEN IS_NULLABLE NO AND ISNULL(COLUMN_DEFAULT) THEN NOT NULL EL…

Adobe Illustrator矢量绘图软件win/mac软件下载安装

一、软件概述 1.1 Adobe Illustrator简介 Adobe Illustrator是一款由Adobe Systems开发的强大矢量绘图软件&#xff0c;专为设计师、艺术家及图形专家设计。它广泛应用于平面设计、插画、UI设计、图标设计、排版及数字媒体制作等领域。Illustrator以其独特的矢量图形处理能力…

Datawhale X 魔搭 AI夏令营第四期 | AIGC文生图——进阶上分 实战优化 Task3笔记

Hi&#xff0c;大家好&#xff0c;我是半亩花海。在上一个任务中&#xff0c;我们逐行精读baseline&#xff0c;掌握了利用AI工具提升学习效率&#xff0c;并制作了话剧连环画&#xff0c;初步了解Secpter WebUI。今天&#xff0c;我们将深入探讨微调的基本原理及其参数&#x…

海外版多语言互助盘三三复制超级人脉系统

此套源码是全新二开的超级人脉系统&#xff0c;面向海外操作新增多语言&#xff0c;后台可新增其他语言.

【图机器学习系列】(二)从传统机器学习角度理解图(一)

微信公众号&#xff1a;leetcode_algos_life&#xff0c;代码随想随记 小红书&#xff1a;412408155 CSDN&#xff1a;https://blog.csdn.net/woai8339?typeblog &#xff0c;代码随想随记 GitHub: https://github.com/riverind 抖音【暂未开始&#xff0c;计划开始】&#xf…

java 中的设计模式

文章目录 一、前言二、设计模式的分类三、设计模式的原则1、开闭原则&#xff08;Open Close Principle&#xff09;2、里氏代换原则&#xff08;Liskov Substitution Principle&#xff09;3、依赖倒转原则&#xff08;Dependence Inversion Principle&#xff09;4、接口隔离…

【案例55】WebSphere非root用户启动方案

问题背景 很多项目为了安全因素考虑&#xff0c;想让在Linux服务器中启动的程序都用非root用户启动。 解决方案 创建用户和组 现在我们用 root 用户登录&#xff0c;并创建用户和组。 ##创建用户 [rootnc-test ~]# useradd wasadmin##修改密码 [rootnc-test~]# passwd was…

AT 指令和WIFI模组

此次使用到的wifi模组是乐鑫的wifi模组esp8684&#xff0c;该wifi模组内部集成了MQTT协议 串口发送AT指令与单片机进行通信&#xff0c;一下是ESP8684的管脚布局。 ESP8684管脚描述&#xff1a; 注&#xff1a;30 和 31 号管脚是用于调试的管脚&#xff0c;20 与 21 号管脚才是…

allure实现测试报告的生成

在测试用例编写完成之后&#xff0c;我们可以通过allure生成测试报告 一、配置java环境变量&#xff0c;jdk17的版本 二、安装allure-commanlie工具&#xff0c;可在官网下载&#xff0c;也可通过百度网盘下载 链接: https://pan.baidu.com/s/10123Iv2f7Ht476feDiP0Yw 提取码…

视频智能分析平台烟火检测视频安防监控烟火算法识别应用方案

烟火检测算法的应用方案主要围绕其核心技术——深度学习&#xff08;特别是卷积神经网络CNN&#xff09;和计算机视觉技术展开&#xff0c;旨在实现对监控视频中的烟雾和火焰进行实时、准确的检测与识别。以下是一个详细的烟火检测算法应用方案&#xff1a; 一、技术原理 烟火…

如何使用Python进行餐馆满意度分析——K-means算法与NLP情感分析实战

&#x1f393; 作者&#xff1a;计算机毕设小月哥 | 软件开发专家 &#x1f5a5;️ 简介&#xff1a;8年计算机软件程序开发经验。精通Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等技术栈。 &#x1f6e0;️ 专业服务 &#x1f6e0;️ 需求定制化开发源码提…

TOP10漏洞原理

## 本人为学习网安不久的新人&#xff0c;记一次学习笔记&#xff0c;有缺陷或者表述不对的地方欢迎大家指出&#xff0c;感谢&#xff01; ## 1、sql注入&#xff1a;web应用程序对用户输入的数据没有进行过滤&#xff0c;或者过滤不严&#xff0c;就把sql语句拼接进数据库…

【C++ Primer Plus习题】3.2

问题: 解答: #include <iostream> using namespace std;const int FOOT_TO_INCH 12; const double INCH_TO_MI 0.0254; const float KG_TO_POUND 2.2;int main() {int inch 0;int foot 0;int inchs 0;double mi 0;int pound 0;double kg 0;double BMI 0;cout &…

QEMU/KVM 虚拟机显卡透传 (vfio-pci)

首发日期 2024-08-22, 以下为原文内容: 本文介绍将 PCIE 设备 (显卡) 透传给 QEMU/KVM 虚拟机的一种方法, 基于 Linux 内核的 vfio-pci 功能. 透传 (pass through) 之后, 虚拟机内可以直接操作 (使用) 显卡硬件, 就像物理机那样, 几乎没有虚拟化的性能损失. 这里是 穷人小水滴…

电商分账系统整个原理 空中分账具体解决方案

电商分账系统最近比较火&#xff0c;比如大家做天猫的时候&#xff0c;直接可以通过网商贷把钱拿出来&#xff0c;但抖店没有这种贷款&#xff0c;大家都有一种不想进对公的方式&#xff0c;那系统本身就是虚拟户加操作系统&#xff0c;虚拟户是银行开的&#xff0c;银行开就需…