编译aws并访问minio

news2024/11/14 11:54:11

Aws

amazon (S3) 是一个公开的服务,Web 应用程序开发人员可以使用它存储数字资产,包括图片、视频、音乐和文档。 S3 提供一个 RESTful API 以编程方式实现与该服务的交互.

MinIO是兼容AWS SDK,所以可以通过aws访问minio文件系统。

指导文档:https://docs.aws.amazon.com/sdk-for-cpp/v1/developer-guide/getting-started.html

Aws安装
Windows系统
vcpkg install aws-sdk-cpp 命令行在线安装

需要先安装vcpkg,参看https://blog.csdn.net/baidu_16370559/article/details/140697821?spm=1001.2014.3001.5501

在powershell输入下面命令

vcpkg search aws-sdk-cpp

vcpkg install aws-sdk-cpp[s3]:x64-windows

报错,不能通过

源码安装:

参看https://docs.aws.amazon.com/zh_cn/sdk-for-cpp/v1/developer-guide/setup-windows.html

前提要求:

Install CMake (minimum version 3.13) ,可以在powershell 输入cmake --version 查看版本,这里cmake 的版本是

  1. 源码下载:GitHub - aws/aws-sdk-cpp: AWS SDK for C++ 有2种办法
  1. 直接从git下载zip文件

这里下载的版本是aws-sdk-cpp-1.11.370.zip.  ctr/aws-crt-cpp目录为空,需要手动从git下载.

使用的aws-crt-cpp版本是v0.27.4,此时aws-crt-cpp目录的ctr目录下的各个文件夹也是空的。需要手动下载ctr目录下各文件夹的源码

  1. 在powershell通过git下装

前提条件是:安装git

在powershell 输入 git clone --recurse-submodules GitHub - aws/aws-sdk-cpp: AWS SDK for C++ 这样通过git下载。这种办法只能下载main分支的代码。

这种办法不一定会把所有的文件都下载,也可能需要手动下载依赖库。

  1. mkdir sdk_build  cd sdk_build
  2. Generate build files

cmake ..\aws-sdk-cpp-1.11.370 -DCMAKE_BUILD_TYPE=Release -DBUILD_ONLY="s3" -DCMAKE_PREFIX_PATH="E:\code\aws\aws\aws-sdk-cpp-1.11.370\install" -DENABLE_TESTING=OFF

  1. cmake --build  --config=Debug
  2. cmake --install  --config=Debug

注意:步骤3过程中,使用powershell编译出错.改成cmake-gui进行编译。

ALL_BUILD右键,生成

单击INSTALL,右键,仅用于项目,仅生成INSTALL

Windows系统使用aws

VS2019

直接使用aws,编译测试demo会报错。

解决方法

官方文档有说到,要添加USE_IMPORT_EXPORT和

USE_WINDOWS_DLL_SEMANTICS两个宏,所以这个问题是符号导出的问题

QT

解决办法:

在pro文件加上预定义

DEFINES +=USE_IMPORT_EXPORT

DEFINES +=USE_WINDOWS_DLL_SEMANTICS

Linux系统
vcpkg install aws-sdk-cpp 命令行在线安装

  * aws-c-auth:x64-linux@0.7.22

  * aws-c-cal:x64-linux@0.6.15

  * aws-c-common:x64-linux@0.9.21

  * aws-c-compression:x64-linux@0.2.18

  * aws-c-event-stream:x64-linux@0.4.2

  * aws-c-http:x64-linux@0.8.2

  * aws-c-io:x64-linux@0.14.9

  * aws-c-mqtt:x64-linux@0.10.4

  * aws-c-s3:x64-linux@0.5.10

  * aws-c-sdkutils:x64-linux@0.1.16

  * aws-checksums:x64-linux@0.1.18

  * aws-crt-cpp:x64-linux@0.26.12

    aws-sdk-cpp[core,dynamodb,kinesis,s3]:x64-linux@1.11.352

  * s2n:x64-linux@1.4.16

没通过,应该因为需要依赖太多第三方库,直接在线安装很多时候下载不成功

源码安装

下载地址:GitHub - aws/aws-sdk-cpp: AWS SDK for C++

参考:Build the AWS SDK for C++ on Linux/macOS - AWS SDK for C++

前提:

GNU Compiler Collection (GCC) 4.9 or later, or

Install CMake (minimum version 3.13

额外的要求:

sudo apt-get install libcurl4-openssl-dev libssl-dev uuid-dev zlib1g-dev libpulse-dev

安装步骤:

  1. 下载源码

 源码地址:GitHub - aws/aws-sdk-cpp: AWS SDK for C++  

 有2种办法

  1. 直接从git下载zip文件

这里下载的版本是aws-sdk-cpp-1.11.370.zip. 如果在windows系统已经下载好源码,可以直接拿来用。aws-crt-cpp版本是v0.27.4。此时aws-crt-cpp目录的ctr目录下的各个文件夹也是空的。需要手动下载ctr目录下各文件夹的源码

  1. 在shell 通过git下装

前提条件是:安装git

git clone --recurse-submodules GitHub - aws/aws-sdk-cpp: AWS SDK for C++

注意事项:ctr/aws-crt-cpp目录下的很多文件可能拉不下来,需要手动从git下载.

  1. mkdir sdk_build   cd sdk_build
  2. Generate build files

这里我使用的是cmake ../aws-sdk-cpp -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/root/software/aws/aws/install/ -DBUILD_ONLY="s3" -DENABLE_TESTING=OFF

  1. make -j4
  2. make install

注意事项:

我这里A.直接从git下载zip文件,编译通过后。调用aws库,会出现libaws-c-s3.so库缺少

libcrypto.so.3。因为我的电脑openssl的版本只有libcrypto.so.1.版本太低了。需要升版libcrypto。

升版方法参考:编译openssl文章。具体操作是从Downloads | Library下载源码编译安装,然后设置软连接,同时把openssl的lib库加载环境变量。

客户端使用aws

要求

  1. 最开始必须调用Aws::InitAPI
  2. 在程序关闭前必须调用Aws::ShutdownAPI
  3. 其他的aws的api在Aws::InitAPI和Aws::ShutdownAPI之间调用

QT通过aws访问minio

pro配置

INCLUDEPATH += $$PWD/install/include

DEPENDPATH += $$PWD/install/include

DESTDIR=$$PWD/bin

 LIBS += -L$$PWD/install/lib/   -laws-c-auth -laws-c-cal\

-laws-c-common -laws-c-compression -laws-c-event-stream -laws-checksums -laws-c-http -laws-c-io\

-laws-c-mqtt -laws-cpp-sdk-core -laws-crt-cpp -laws-c-s3 -laws-c-sdkutils -ls2n -laws-cpp-sdk-s3

代码编写

参看:https://docs.aws.amazon.com/sdk-for-cpp/v1/developer-guide/examples-s3-objects.html

#ifndef MINIOSERVICE_H

#define MINIOSERVICE_H

#include <QMutex>

#include <QString>

#include <QStringList>

#include "aws/s3/S3Client.h"

#include "aws/core/Aws.h"

#include "aws/core/auth/AWSCredentialsProvider.h"

#include "aws/s3/model/PutObjectRequest.h"

#include "aws/s3/model/GetObjectRequest.h"

#include "aws/s3/model/CreateBucketRequest.h"

#include "aws/s3/model/DeleteObjectRequest.h"

#include "aws/s3/model/DeleteBucketRequest.h"

#include "aws/s3/model/ListObjectsRequest.h"

using namespace std;

using namespace Aws::S3;

using namespace Aws::S3::Model;

struct RetStatus

{

    int nRetCode = 0;

    QString msg ="成功";

};

class MinioService

{

public:

    MinioService();

    ~MinioService();

public:

    //单例

    static MinioService * GetInstance();

    //释放

    static void DeleteInstance();

    /**

     * @brief LoginMinio 登录minio文件系统

     * @return 错误码

     */

    RetStatus LoginMinio();

    RetStatus CreateBucket(QString Bucketname);

    RetStatus GetBuckets(QStringList& bucketsname);

    RetStatus GetBucketFile(QString Bucketname,QStringList& fileList);

    /**

     * @brief DownLoadFile 从minio文件系统下载文件

     * @param strBucket   桶的名称

     * @param strObject   需下装的内容

     * @param strSavePath  下载到本地的路径

     * @return   错误码

     */

    RetStatus DownLoadFile(QString strBucket,QString strObject,QString strSavePath);

    /**

     * @brief UpLoadFile 把本地文件上传到minio文件系统

     * @param strBucket  桶的名称

     * @param strObject  存放到minio的文件路径

     * @param strFilePath 本地文件路径

     * @return

     */

    RetStatus UpLoadFile(QString strBucket,QString strObject,QString strFilePath);

    RetStatus DeleteFile(QString strBucket,QString strObject);

    // // 删除Bucket,一定要先删除文件,再删除Bucket

    RetStatus DeleteBucket(QString strBucket);

private:

    static MinioService *m_pInstance;

    static QMutex m_mutex;

    S3Client* m_client;

    Aws::SDKOptions m_options;

};

#endif // MINIOSERVICE_H

#include "minioservice.h"

#include <QFile>

MinioService *MinioService::m_pInstance = nullptr;

QMutex MinioService::m_mutex;

MinioService::MinioService()

{

    m_client = nullptr;

    m_options.loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Debug;

    Aws::InitAPI(m_options);

    Aws::Client::ClientConfiguration cfg;

    cfg.endpointOverride = "127.0.0.1:3003";

    cfg.scheme = Aws::Http::Scheme::HTTP;

    cfg.verifySSL = false;

    Aws::Auth::AWSCredentials cred("minioadmin", "minioadmin");

    m_client = new S3Client(cred, cfg, Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy::Always, false,

    Aws::S3::US_EAST_1_REGIONAL_ENDPOINT_OPTION::NOT_SET);

}

MinioService::~MinioService()

{

    Aws::ShutdownAPI(m_options);

    if(m_client)

    {

        delete m_client;

        m_client = nullptr;

    }

}

MinioService *MinioService::GetInstance()

{

    if(nullptr == m_pInstance)

    {

        m_mutex.lock();

        if( nullptr == m_pInstance)

        {

            m_pInstance =  new MinioService();

        }

        m_mutex.unlock();

    }

    return m_pInstance;

}

void MinioService::DeleteInstance()

{

    m_mutex.lock();

    if(m_pInstance)

    {

        delete m_pInstance;

        m_pInstance = nullptr;

    }

    m_mutex.unlock();

}

RetStatus MinioService::LoginMinio()

{

    RetStatus Reture;

    if(m_client == nullptr)

    {

        Reture.nRetCode = -1;

        Reture.msg = "创建连接客户端不成功。";

        return  Reture;

    }

    auto response = m_client->ListBuckets();

    if (response.IsSuccess())

    {

        Reture.nRetCode = 0;

        Reture.msg = QString("登录minio文件系统成功.");

        return Reture;

    }

    else

    {

        Reture.nRetCode = 1;

        Reture.msg = "登录失败";

    }

    return Reture;

}

RetStatus MinioService::CreateBucket(QString Bucketname)

{

    RetStatus Reture;

    if(m_client == nullptr)

    {

        Reture.nRetCode = -1;

        Reture.msg = "创建连接客户端不成功。";

        return  Reture;

    }

    Aws::S3::Model::CreateBucketRequest create_bucket_request;

    create_bucket_request.SetBucket(Bucketname.toStdString());

    create_bucket_request.SetCreateBucketConfiguration({});

    auto create_bucket_outcome = m_client->CreateBucket(create_bucket_request);

    if (create_bucket_outcome.IsSuccess())

    {

        Reture.nRetCode = 0;

        Reture.msg = "创建Bucket成功。";

        return  Reture;

    }

    else

    {

        string strErr = create_bucket_outcome.GetError().GetMessage();

        Reture.nRetCode = 2;

        Reture.msg = "创建Bucket失败:" + QString::fromStdString(strErr) ;

    }

    return Reture;

}

RetStatus MinioService::GetBuckets(QStringList& bucketsname)

{

    bucketsname.clear();

    RetStatus Reture;

    if(m_client == nullptr)

    {

        Reture.nRetCode = -1;

        Reture.msg = "创建连接客户端不成功。";

        return  Reture;

    }

    auto response = m_client->ListBuckets();

    if (response.IsSuccess())

    {

        auto buckets = response.GetResult().GetBuckets();

        for(auto bucket :buckets)

        {

            bucketsname.append(QString::fromStdString(bucket.GetName()));

        }

        Reture.nRetCode = 0;

        Reture.msg = "获取buckets成功。";

    }

    else

    {

        Reture.nRetCode = 3;

        string strErr = response.GetError().GetMessage();

        Reture.msg = "获取buckets不成功:" + QString::fromStdString(strErr) ;

    }

    return Reture;

}

RetStatus MinioService::GetBucketFile(QString Bucketname, QStringList &fileList)

{

    fileList.clear();

    RetStatus Reture;

    if(m_client == nullptr)

    {

        Reture.nRetCode = -1;

        Reture.msg = "创建连接客户端不成功。";

        return  Reture;

    }

    Aws::S3::Model::Bucket temps{};

    std::string stringK = Bucketname.toStdString();

    temps.SetName(stringK);

    /// 查找MINIO相关数据

    Aws::S3::Model::ListObjectsRequest objects_request;

    objects_request.WithBucket(temps.GetName());   /// 设置桶路径

    auto list_objects_outcome = m_client->ListObjects(objects_request);  /// 判断存储桶及相关连接是否有效

    if (list_objects_outcome.IsSuccess())

    {

        Aws::Vector<Aws::S3::Model::Object> object_list = list_objects_outcome.GetResult().GetContents();

        for (auto  s3_object : object_list)

        {

            QString filename =QString::fromStdString(s3_object.GetKey());

            fileList.append(filename);

        }

        Reture.nRetCode = 0;

        Reture.msg = "获取文件列表成功。";

    }

    else

    {

        Reture.nRetCode = 8;

        string strErr = list_objects_outcome.GetError().GetMessage();

        Reture.msg = "获取文件列表失败:" + QString::fromStdString(strErr) ;

    }

    return Reture;

}

RetStatus MinioService::DownLoadFile(QString strBucket, QString strObject, QString strSavePath)

{

    RetStatus Reture;

    if(m_client == nullptr)

    {

        Reture.nRetCode = -1;

        Reture.msg = "创建连接客户端不成功。";

        return  Reture;

    }

    Aws::S3::Model::GetObjectRequest object_request;

    object_request.WithBucket(strBucket.toStdString().c_str()).WithKey(strObject.toStdString().c_str());

    auto get_object_outcome = m_client->GetObject(object_request);

    if (get_object_outcome.IsSuccess())

    {

        Aws::IOStream &local_file = get_object_outcome.GetResult().GetBody();

        std::istreambuf_iterator<char> begin(local_file);

        std::istreambuf_iterator<char> end;

        std::string buffer(begin, end); // 读取整个文件内容

        QFile file_(strSavePath);

        if(file_.open(QIODevice::ReadWrite | QIODevice::Truncate))//以截取方式打开文件,文件原有的内容全部被删除

        {

            file_.write(QByteArray::fromStdString(buffer));

            file_.close();

            Reture.nRetCode = 0;

            Reture.msg = "下载文件成功。";

        }

        else

        {

            Reture.nRetCode = 4;

            Reture.msg = "下载文件失败:创建本地保存文件失败";

        }

    }

    else

    {

        string strErr = get_object_outcome.GetError().GetMessage() ;

        Reture.nRetCode = 5;

        Reture.msg = "下载文件失败:" + QString::fromStdString(strErr);

    }

    return  Reture;

}

RetStatus MinioService::UpLoadFile(QString strBucket, QString strObject, QString strFilePath)

{

    RetStatus Reture;

    if(m_client == nullptr)

    {

        Reture.nRetCode = -1;

        Reture.msg = "创建连接客户端不成功。";

        return  Reture;

    }

    QFile file(strFilePath);

    bool bOpen = file.open(QIODevice::ReadOnly);

    Aws::S3::Model::PutObjectRequest putObjectRequest;

    putObjectRequest.WithBucket(strBucket.toStdString().c_str()).WithKey(strObject.toStdString().c_str());

    std::shared_ptr<Aws::IOStream> input_data = Aws::MakeShared<Aws::StringStream>("PutObjectInputStream");

    *input_data << file.readAll().toStdString();

    file.close();

    putObjectRequest.SetBody(input_data);

    auto putObjectResult = m_client->PutObject(putObjectRequest);

    if (putObjectResult.IsSuccess())

    {

        Reture.nRetCode = 0;

        Reture.msg = "上传文件成功";

    }

    else

    {

        string strErr = putObjectResult.GetError().GetMessage() ;

        Reture.nRetCode = 6;

        Reture.msg = "上传文件失败:" + QString::fromStdString(strErr);

    }

    return  Reture;

}

RetStatus MinioService::DeleteFile(QString strBucket, QString strObject)

{

    RetStatus Reture;

    if(m_client == nullptr)

    {

        Reture.nRetCode = -1;

        Reture.msg = "创建连接客户端不成功。";

        return  Reture;

    }

    Aws::S3::Model::DeleteObjectRequest delete_object_request;

    delete_object_request.WithBucket(strBucket.toStdString().c_str()).WithKey(strObject.toStdString().c_str());

    auto delete_object_outcome = m_client->DeleteObject(delete_object_request);

    if (delete_object_outcome.IsSuccess())

    {

        Reture.nRetCode = 0;

        Reture.msg = "删除文件成功";

    }

    else

    {

        string strErr = delete_object_outcome.GetError().GetMessage() ;

        Reture.nRetCode = 7;

        Reture.msg = "删除文件失败:" + QString::fromStdString(strErr);

    }

    return Reture;

}

RetStatus MinioService::DeleteBucket(QString strBucket)

{

    RetStatus Reture;

    if(m_client == nullptr)

    {

        Reture.nRetCode = -1;

        Reture.msg = "创建连接客户端不成功。";

        return  Reture;

    }

    Aws::S3::Model::DeleteBucketRequest delete_bucket_request;

    delete_bucket_request.SetBucket(strBucket.toStdString().c_str());

    auto delete_bucket_outcome = m_client->DeleteBucket(delete_bucket_request);

    if (delete_bucket_outcome.IsSuccess())

    {

        Reture.nRetCode = 0;

        Reture.msg = "删除bucket成功";

    }

    else

    {

        string strErr = delete_bucket_outcome.GetError().GetMessage() ;

        Reture.nRetCode = 7;

        Reture.msg = "删除文件失败:" + QString::fromStdString(strErr);

    }

    return Reture;

}

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

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

相关文章

CSS知识点详解:display+float

display&#xff1a;浮动 1.block&#xff1a;使元素呈现为块级元素&#xff0c;可设置宽高 display: block; 特点&#xff1a;使元素呈现为块级元素&#xff0c;即该元素会以新行开始&#xff0c;占据整行的宽度&#xff0c;即使其宽度未满。 例子&#xff1a; 2.inline&a…

队列(笔记)

文章目录 1. 概念2. 实现方式3. 复杂度其他 4. 实际应用5. 内容出处 1. 概念 队列&#xff1a;其实就是排队。像我们在银行窗口取钱、车站买车票等都可以叫队列。 特点&#xff1a;队列只允许在后端(rear)进行插入操作&#xff0c;在前端(front)进行删除操作(即先进先出…

算法刷题记录 八十五【图论的广度优先搜索理论基础】

前言 图论章节第2篇。 第1篇&#xff1a;记录 八十二【图论理论基础及深度优先搜索算法】&#xff1b; 本文&#xff1a;记录 八十五【图论的广度优先搜索理论基础】 一、广度优先搜索理论基础 广度优先搜索理论基础 参考链接 1.1 知识点框架 1.2 模拟广度搜索的过程 在有向…

Llama 3.1深度解析:405B、70B及8B模型的多语言与长上下文处理能力

Llama 3.1 发布了&#xff01;今天我们迎来了 Llama 家族的新成员 Llama 3.1 进入 Hugging Face 平台。我们很高兴与 Meta 合作&#xff0c;确保在 Hugging Face 生态系统中实现最佳集成。Hub 上现有八个开源权重模型 (3 个基础模型和 5 个微调模型)。 Llama 3.1 有三种规格: …

字符串拼接和反转

定义一个方法&#xff0c;把int数组中的数据按照指定的格式拼接成一个字符串 调用该方法&#xff0c;并在控制台输出结果 例如&#xff1a; 数组为 int[] arr [1,2,3]; 执行方法后的输出结果为:[1,2,3] package stringdemo;public class StringDemo3 {public static void…

洋牡丹:多彩花语与深邃寓意

一、洋牡丹概述 洋牡丹&#xff0c;学名为花毛茛&#xff0c;其名称的由来颇为有趣。因花型酷似牡丹花&#xff0c;且从国外引入栽培&#xff0c;故得 “洋牡丹” 这一亲切的称呼。 洋牡丹的常见品种繁多&#xff0c;有单瓣和重瓣之分。单瓣的洋牡丹清新雅致&#xff0c;花瓣舒…

docker 最新可用镜像源地址

无论是docker桌布版本&#xff0c;还是linux版本通用 直接更换镜像源地址即可&#xff1a;亲测目前可用 { "registry-mirrors": ["https://0c105db5188026850f80c001def654a0.mirror.swr.myhuaweicloud.com","https://5tqw56kt.mirror.aliyuncs.com&…

大模型基于指令的知识编辑:InstructEdit技术

人工智能咨询培训老师叶梓 转载标明出处 在知识更新和编辑方面&#xff0c;大模型在特定任务上表现出色&#xff0c;但在面对不同任务时往往力不从心&#xff0c;需要为每个任务单独设计编辑器&#xff0c;这在一定程度上限制了其应用范围。为了解决这一问题&#xff0c;浙江大…

二十二、状态模式

文章目录 1 基本介绍2 案例2.1 Season 接口2.2 Spring 类2.3 Summer 类2.4 Autumn 类2.5 Winter 类2.6 Person 类2.7 Client 类2.8 Client 类的运行结果2.9 总结 3 各角色之间的关系3.1 角色3.1.1 State ( 状态 )3.1.2 ConcreteState ( 具体的状态 )3.1.3 Context ( 上下文 )3.…

【ARM+Codesys 客户案例 】 基于RK3568/A40i/STM32+CODESYS开发AGV运动控制器,支持国产定制

在过去&#xff0c;步科更多的是为AGV客户提供单一、高性能的低压伺服核心部件产品&#xff0c;而现在&#xff0c;步科基于 CODESYS 开发了一款面向AGV机器人的特种控制器 - 青龙1号&#xff0c;开始提供以步科AGV运动控制器FD1X4S系列低压伺服Green系列HMI等为核心的AGV总线控…

keepalived理论--实验

一 . 高可用集群 1.1 集群类型 LB &#xff1a; Load Balance 负载均衡 LVS/HAProxy/nginx &#xff08; http/upstream, stream/upstream &#xff09; HA &#xff1a; High Availability 高可用集群 数据库、 Redis SPoF: Single Point of Failure &#xff0c;解决…

2004-2023华为杯数学建模优秀参考论文

笔者整理了2004-2023年华为杯研究生数学建模全部优秀论文和赛题&#xff0c;内容齐全&#xff0c;适合将要参加建模比赛的朋友学习使用。 免费优秀论文获取联系&#xff1a; 建模忠哥小师妹 2004-2023历届华为杯研究生数学建模优秀论文合集&#xff1a;

【数学分析笔记】第2章第1节实数系的连续性(2)

2. 数列极限 2.1 实数系的连续性 2.1.3 确界存在定理 【定理2.1.1】&#xff08;确界存在定理——实数系连续性定理&#xff09;非空有上界的数集必有上确界&#xff0c;非空有下界的数集必有下确界。 【证】&#xff08;写了一些我自己的理解&#xff0c;欢迎数院大神批评指…

Linux基础知识学习(二)

一. 常用基本命令 1. 目录管理 1> 绝对路径、相对路径 绝对路径路径的全称&#xff1a;C:\ProgramData\360safe\xxx.xx 比如说 360safe 目录下&#xff0c;那这个 xxx.xx 文件&#xff0c;对应我们的相对配置就 /xxx.xx cd &#xff1a; 切换目录命令&#xff01; ./ &…

【html+css 绚丽Loading】-000001 双极乾坤盘

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享htmlcss 绚丽Loading&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495…

【信创】麒麟打包工具初体验

往期好文&#xff1a;关于信创系统&#xff08;麒麟、统信、中科方德&#xff09;的10个问题与答复&#xff08;二&#xff09; Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于麒麟桌面操作系统上麒麟打包工具的介绍与使用的文章。麒麟打包工具是一款专门为麒麟…

C/C++ 不定参函数

C语言不定参函数 函数用法总结 Va_list 作用&#xff1a;类型定义&#xff0c;生命一个变量&#xff0c;该变量被用来访问传递给不定参函数的可变参数列表用法&#xff1a;供后续函数进调用&#xff0c;通过该变量访问参数列表 typedefchar* va_list; va_start 作用&#xff…

解决MSPM0G3507芯片锁住的问题

编译环境&#xff1a;Windows 开发软件&#xff1a;Keil 开发主控&#xff1a;立创的MSPM0G3507 我们在MSPM0G3507时&#xff0c;常为芯片锁住烦恼&#xff0c;常见的锁死是因为使用了ST-Link&#xff0c;这里展示的是使用ST-Link后芯片锁死的解决步骤。 现象&a…

MySQL数据库入门,pycharm连接数据库—详细讲解

一.安装MySQL 1.常用MySQL5.7&#xff0c;首先安装MySQL&#xff0c; &#xff08;一&#xff09; &#xff08;二&#xff09; &#xff08;三&#xff09; &#xff08;四&#xff09; &#xff08;五&#xff09; 2.配置环境变量 打开MySQL安装路径&#xff0c;在其中找到…

python:画函数积分图

《高等数学》同济大学版 P209 编写 test_diff_area.py 如下 # -*- coding: utf-8 -*- """ 函数积分图 y x^3 -x^2 -x1 """ import numpy as np import matplotlib.pyplot as plt from matplotlib.patches import Polygondef func(x):return …