Qt/C++ 调用迅雷开放下载引擎(ThunderOpenSDK)下载数据资源

news2024/11/28 10:46:47

目录导读

    • 前言
    • ThunderOpenSDK 简介
      • 参考 xiaomi_Thunder_Cloud 示例
      • ThunderOpenSDK 下载问题

前言

在对以前老版本的exe执行程序进行研究学习的时候,发现以前的软件是使用的ThunderOpenSDK这个迅雷开放下载引擎进行的项目数据下载,于是在网上搜索一番找到了相关内容,但是不知道为什么了相关资料相当少,不过用是真的好用,于是仔细的研究了一下。


ThunderOpenSDK 简介

ThunderOpenSDK 是一个迅雷开放下载引擎的 SDK,允许开发者在自己的应用程序中集成迅雷的下载功能。该 SDK 提供了丰富的接口,支持多种下载任务的管理,包括任务的创建、启动、停止、删除等操作。此外,SDK 还支持设置下载速度限制、代理、用户代理等功能,以满足不同应用场景的需求。
出自:ThunderOpenSDK 使用教程
相关内容参考:

  1. 迅雷开放下载引擎(ThunderOpenSDK)使用指南

  2. ThunderOpenSDK 使用教程

  3. 配置云平台ip和端口 云平台接口

  4. GitHub: ThunderOpenSDK

ThunderOpenSDK 不需要再进行编译,直接附加到项目中就能直接使用,甚至示例程序都写好了,只管调用。
GitHub示例中有0.CurUseCommonLib360Jisu_Thunder_Cloudliebao_Thunder_Cloudxiaomi_Thunder_CloudXunleiDownload_Old 5个版本的示例,
可以根据需求任选一个
在这里插入图片描述
通过查看xldl.dll文件的属性信息和Github上的声明,
我都毫不怀疑这些库文件是不是是从某个软件上扒下来的。

参考 xiaomi_Thunder_Cloud 示例

xiaomi_Thunder_Cloud 迅雷云加速开发平台版本示例;
在这里插入图片描述
打开xldl.h文件可以发现xldl.dll的接口和数据结构都已经声明好还有注释,只管调用:

  • xldl.h:
#pragma once

// 所有结构体定义按1字节对齐
#pragma pack(push, 1)
struct DownTaskParam
{
	DownTaskParam()
	{
		memset(this, 0, sizeof(DownTaskParam));
		nReserved1		 = 5;
		bReserved			 = FALSE;
		DisableAutoRename	 = FALSE;
		IsOnlyOriginal		 = FALSE;
		IsResume			 = TRUE;
	}
    int nReserved;
	wchar_t szTaskUrl[2084];          // 任务URL
	wchar_t szRefUrl[2084];           // 引用页
	wchar_t szCookies[4096];          // 浏览器cookie
	wchar_t szFilename[MAX_PATH];     // 下载保存文件名.
	wchar_t szReserved0[MAX_PATH];
	wchar_t szSavePath[MAX_PATH];     // 文件保存目录
	HWND  hReserved;
	BOOL bReserved; 
	wchar_t szReserved1[64];
	wchar_t szReserved2[64];
	BOOL IsOnlyOriginal;            // 是否只从原始地址下载
	UINT nReserved1;
	BOOL DisableAutoRename;         // 禁止智能命名
	BOOL IsResume;                  // 是否用续传
	DWORD reserved[2048];
};
enum  DOWN_TASK_STATUS
{
	NOITEM = 0,
	TSC_ERROR,
	TSC_PAUSE,
	TSC_DOWNLOAD,
	TSC_COMPLETE,
	TSC_STARTPENDING,
	TSC_STOPPENDING
};
enum TASK_ERROR_TYPE
{
	TASK_ERROR_UNKNOWN	   =			0x00,   // 未知错误
	TASK_ERROR_DISK_CREATE =			0x01,   // 创建文件失败
	TASK_ERROR_DISK_WRITE =				0x02,   // 写文件失败
	TASK_ERROR_DISK_READ =				0x03,   // 读文件失败
	TASK_ERROR_DISK_RENAME =			0x04,   // 重命名失败
	TASK_ERROR_DISK_PIECEHASH =			0x05,   // 文件片校验失败
	TASK_ERROR_DISK_FILEHASH =			0x06,   // 文件全文校验失败
	TASK_ERROR_DISK_DELETE =			0x07,   // 删除文件失败失败
	TASK_ERROR_DOWN_INVALID =			0x10,   // 无效的DOWN地址
	TASK_ERROR_PROXY_AUTH_TYPE_UNKOWN = 0x20,   // 代理类型未知
	TASK_ERROR_PROXY_AUTH_TYPE_FAILED = 0x21,   // 代理认证失败
	TASK_ERROR_HTTPMGR_NOT_IP =			0x30,   // http下载中无ip可用
	TASK_ERROR_TIMEOUT =				0x40,   // 任务超时
	TASK_ERROR_CANCEL =					0x41,   // 任务取消
    TASK_ERROR_TP_CRASHED=              0x42,   // MINITP崩溃
    TASK_ERROR_ID_INVALID =             0x43,   // TaskId 非法
};
struct DownTaskInfo
{
	DownTaskInfo()
	{
		memset(this, 0, sizeof(DownTaskInfo));
		stat		= TSC_PAUSE;
		fail_code	= TASK_ERROR_UNKNOWN;
		fPercent = 0;
		bIsOriginUsable = false;
		fHashPercent = 0;
	}
	DOWN_TASK_STATUS	stat;
	TASK_ERROR_TYPE		fail_code;
	wchar_t		szFilename[MAX_PATH];
	wchar_t		szReserved0[MAX_PATH];
	__int64     nTotalSize;         // 该任务总大小(字节)
	__int64     nTotalDownload;     // 下载有效字节数(可能存在回退的情况)
	float		fPercent;           // 下载进度
	int			nReserved0;
	int			nSrcTotal;          // 总资源数
	int			nSrcUsing;          // 可用资源数
	int			nReserved1;
	int			nReserved2;
	int			nReserved3;
	int			nReserved4;
	__int64     nReserved5;
	__int64		nDonationP2P;       // p2p贡献字节数
	__int64		nReserved6;
	__int64		nDonationOrgin;		// 原始资源共享字节数
	__int64		nDonationP2S;		// 镜像资源共享字节数
	__int64		nReserved7;
	__int64     nReserved8;
	int			nSpeed;             // 即时速度(字节/秒)
	int			nSpeedP2S;          // 即时速度(字节/秒)
	int			nSpeedP2P;          // 即时速度(字节/秒)
	bool		bIsOriginUsable;    // 原始资源是否有效
	float		fHashPercent;       // 现不提供该值
	int			IsCreatingFile;     // 是否正在创建文件
	DWORD		reserved[64];
};
enum DOWN_PROXY_TYPE
{
	PROXY_TYPE_IE	 = 0,
	PROXY_TYPE_HTTP  = 1,
	PROXY_TYPE_SOCK4 = 2,
	PROXY_TYPE_SOCK5 = 3,
	PROXY_TYPE_FTP   = 4,
	PROXY_TYPE_UNKOWN  = 255,
};
enum DOWN_PROXY_AUTH_TYPE
{
	PROXY_AUTH_NONE =0,
	PROXY_AUTH_AUTO,
	PROXY_AUTH_BASE64,
	PROXY_AUTH_NTLM,
	PROXY_AUTH_DEGEST,
	PROXY_AUTH_UNKOWN,
};
struct DOWN_PROXY_INFO
{
	BOOL		bIEProxy;
	BOOL		bProxy;
	DOWN_PROXY_TYPE	stPType;
	DOWN_PROXY_AUTH_TYPE	stAType;
	wchar_t		szHost[2048];
	INT32		nPort;
	wchar_t		szUser[50];
	wchar_t		szPwd[50];
	wchar_t		szDomain[2048];
};
struct WSAPROTOCOL_INFOW;

#pragma pack(pop)

namespace DownEngine
{
    extern "C" __declspec(dllimport) BOOL   XL_Init(void);
    extern "C" __declspec(dllimport) BOOL   XL_UnInit(void);
	extern "C" __declspec(dllimport) HANDLE XL_CreateTask(DownTaskParam &stParam);
	extern "C" __declspec(dllimport) BOOL   XL_DeleteTask(HANDLE hTask);
	extern "C" __declspec(dllimport) BOOL   XL_StartTask(HANDLE hTask);
	extern "C" __declspec(dllimport) BOOL   XL_StopTask(HANDLE hTask);
	extern "C" __declspec(dllimport) BOOL   XL_ForceStopTask(HANDLE hTask);
	extern "C" __declspec(dllimport) BOOL   XL_QueryTaskInfo(HANDLE hTask, DownTaskInfo & stTaskInfo); //旧版接口,使用Ex接口替换
	extern "C" __declspec(dllimport) BOOL   XL_QueryTaskInfoEx(HANDLE hTask, DownTaskInfo & stTaskInfo);
	extern "C" __declspec(dllimport) BOOL	XL_DelTempFile(DownTaskParam &stParam);
	extern "C" __declspec(dllimport) void	XL_SetSpeedLimit(INT32 nKBps);
	extern "C" __declspec(dllimport) void	XL_SetUploadSpeedLimit(INT32 nTcpKBps,INT32 nOtherKBps);
	extern "C" __declspec(dllimport) BOOL	XL_SetProxy(DOWN_PROXY_INFO &stProxyInfo);
	extern "C" __declspec(dllimport) void   XL_SetUserAgent(const wchar_t *pszUserAgent);
	extern "C" __declspec(dllimport) BOOL   XL_ParseThunderPrivateUrl(const wchar_t *pszThunderUrl, wchar_t *normalUrlBuffer, INT32 bufferLen);
	extern "C" __declspec(dllimport) BOOL   XL_GetFileSizeWithUrl(const wchar_t * lpURL, INT64& iFileSize);
    extern "C" __declspec(dllimport) BOOL   XL_SetFileIdAndSize(HANDLE hTask, char szFileId[40], unsigned __int64 nFileSize);
	extern "C" __declspec(dllimport) BOOL   XL_SetAdditionInfo( HANDLE task_id, WSAPROTOCOL_INFOW *sock_info, CHAR *http_resp_buf, LONG buf_len );
	extern "C" __declspec(dllimport) HANDLE XL_CreateTaskByURL(const wchar_t *url, const wchar_t *path, const wchar_t *fileName, BOOL IsResume);
	extern "C" __declspec(dllimport) LONG   XL_CreateTaskByThunder(wchar_t *pszUrl, wchar_t *pszFileName, wchar_t *pszReferUrl, wchar_t *pszCharSet, wchar_t *pszCookie);
	extern "C" __declspec(dllimport) LONG   XL_CreateBTTaskByThunder(const wchar_t *pszPath);
};

相关函数的具体说明,可以参考Github上的文档
这一版本没有调用的示例,但是没关系,liebao_Thunder_Cloud这一版本有调用示例;
在这里插入图片描述
参考thunderWrapper.h文件中的thunderWrapper类通过
LoadLibraryGetProcAddress函数调用,使用MSCV2017编译器
并添加<Windows.h>引用,建议添加:

#include <Windows.h>
#include <stdio.h>
#include <Shlwapi.h>
#pragma comment(lib,"Shlwapi")
  • 初始化函数示例:

只需要简单修改init方法,修改xldl.dll的加载路径,其他基本不变;

bool init(PCWSTR pDllPath = L"xldl.dll")
{
    assert(!m_hModule);
    WCHAR szModulePath[MAX_PATH] = { 0 };
     GetModuleFileNameW(NULL, szModulePath, MAX_PATH);
     PathRemoveFileSpecW(szModulePath);  // 拆分路径        新版使用PathCchRemoveFileSpec
    qDebug()<<"[szModulePath] "<<QString::fromWCharArray(szModulePath);
     WCHAR szDllpath[MAX_PATH] = { 0 };
     PathCombineW(szDllpath, szModulePath, L"xldl.dll");  // 连接路径, 新版建议使用 PathCchCombine
     qDebug()<<"[szDllpath] "<<QString::fromWCharArray(szDllpath);
    m_hModule = LoadLibraryW(szDllpath);
    assert(m_hModule);
    if (m_hModule == NULL)
    {
        qDebug()<<"can not load xldl.dll -->";
        throw L"can not load xldl.dll";
    }
    _Init					= (fn_Init)						GetProcAddress(m_hModule, "XL_Init");
    _UnInit					= (fn_UnInit)					GetProcAddress(m_hModule, "XL_UnInit");
    _TaskCreate				= (fn_TaskCreate)				GetProcAddress(m_hModule, "XL_CreateTask");
    _TaskDelete				= (fn_TaskDelete)				GetProcAddress(m_hModule, "XL_DeleteTask");
    _TaskStart				= (fn_TaskStart)				GetProcAddress(m_hModule, "XL_StartTask");
    _TaskPause				= (fn_StopTask)				    GetProcAddress(m_hModule, "XL_StopTask");
    _TaskForcePause         = (fn_StopTask)				    GetProcAddress(m_hModule, "XL_ForceStopTask");
    _TaskQuery				= (fn_TaskQuery)				GetProcAddress(m_hModule, "XL_QueryTaskInfo");
    _TaskQueryEx			= (fn_TaskQueryEx)				GetProcAddress(m_hModule, "XL_QueryTaskInfoEx");
    _LimitSpeed				= (fn_LimitSpeed)				GetProcAddress(m_hModule, "XL_SetSpeedLimit");
    _LimitUploadSpeed		= (fn_LimitUploadSpeed)			GetProcAddress(m_hModule, "XL_SetUploadSpeedLimit");
    _DelTempFile			= (fn_DelTempFile)				GetProcAddress(m_hModule, "XL_DelTempFile");
    _SetProxy				= (fn_SetProxy)                 GetProcAddress(m_hModule, "XL_SetProxy");
    _SetUserAgent			= (fn_SetUserAgent)				GetProcAddress(m_hModule, "XL_SetUserAgent");
    _GetFileSizeWithUrl		= (fn_GetFileSizeWithUrl)		GetProcAddress(m_hModule, "XL_GetFileSizeWithUrl");
    _ParseThunderPrivateUrl = (fn_ParseThunderPrivateUrl)	GetProcAddress(m_hModule, "XL_ParseThunderPrivateUrl");
    _SetAdditionInfo		= (fn_SetAdditionInfo)			GetProcAddress(m_hModule, "XL_SetAdditionInfo");
    _SetFileIdAndSize		= (fn_SetFileIdAndSize)			GetProcAddress(m_hModule, "XL_SetFileIdAndSize");
    _CreateTaskByURL        = (fn_CreateTaskByURL)			GetProcAddress(m_hModule, "XL_CreateTaskByURL");
    _CreateTaskByThunder    = (fn_CreateTaskByThunder)		GetProcAddress(m_hModule, "XL_CreateTaskByThunder");
    _CreateBTTaskByThunder  = (fn_CreateBTTaskByThunder)	GetProcAddress(m_hModule, "XL_CreateBTTaskByThunder");

    CHECKFUNC(_Init, false);
    return _Init() == TRUE;
}

需要注意的是在不同版本中,所包含的方法函数也不一样,例如liebao_Thunder_Cloud 版就没有XL_CreateTaskByURL函数方法,

  • 实际线程调用:

继承QThread类,重写void run() override;方法,获取文件总大小,下载进度,下载有效字节数,即时速度,倒计时等信息,并通过信号槽控制下载的中断和退出。

void QThread_ThunderWrapper::run()
{
 emit IsStart(true);
    bool ISuccessed=false;
    IsQuit=false;
    QString Error="";
    try {
        qDebug()<<"QThread_ThunderWrapper Start!";
        thunderWrapper=new Lib_ThunderWrapper();
        bool ISuccessed=thunderWrapper->init();
        if(!ISuccessed)
            throw QString("Lib_ThunderWrapper 初始化失败!");
        else
            qDebug()<<"thunderWrapper->init : Successed!";

        wchar_t * url=utf8_to_wchar(Urlpath.toStdString().c_str());
        wchar_t * path=utf8_to_wchar(Filepath.toStdString().c_str());
        wchar_t * fileName=utf8_to_wchar(Filename.toStdString().c_str());


        if(!thunderWrapper->CreateTaskByURL(url,path,fileName,TRUE))
        {
            thunderWrapper->unInit();
            throw QString("taskCreate 失败!");
        }
        else
            qDebug()<<"thunderWrapper->taskCreate : Successed!";

        if(!thunderWrapper->taskStart())
        {
            thunderWrapper->taskDelete();
            thunderWrapper->unInit();
            throw QString("taskStart 失败!");
        }
        else
            qDebug()<<"thunderWrapper->taskStart : Successed!";

        //! 1秒查询一次
        msleep(1000);
        DownTaskInfo stTaskInfo;
        while (!IsQuit) {
            if(thunderWrapper->taskQueryEx(stTaskInfo))
            {
                if(stTaskInfo.stat==TSC_ERROR)
                {
                    emit Current_status("下载失败!",TSC_ERROR);
                    throw QString("TSC_ERROR: fail_code:%1").arg(stTaskInfo.fail_code);
                }
                else if(stTaskInfo.stat==TSC_PAUSE)
                {
                    emit Current_status("下载暂停!",TSC_PAUSE);
                }
                else if(stTaskInfo.stat==TSC_DOWNLOAD)
                {
                    emit Current_status("正在下载...",TSC_PAUSE);
                    emit Down_Speed(stTaskInfo.nSpeed);
                    emit ProgressBar((int)stTaskInfo.fPercent*100);
                    emit SendDownsize(stTaskInfo.nTotalDownload,stTaskInfo.nTotalSize);
                    if(stTaskInfo.nSpeed>0)
                        emit Time_Remaining((stTaskInfo.nTotalSize-stTaskInfo.nTotalDownload)/stTaskInfo.nSpeed);
                }
                else if(stTaskInfo.stat==TSC_COMPLETE)
                {
                    ISuccessed=true;
                    IsQuit=true;
                    emit Current_status("下载完成",TSC_COMPLETE);
                    emit Down_Speed(stTaskInfo.nSpeed);
                    emit ProgressBar((int)stTaskInfo.fPercent*100);
                    emit SendDownsize(stTaskInfo.nTotalDownload,stTaskInfo.nTotalSize);
                    emit Time_Remaining(0);
                    break;
                }
                else if(stTaskInfo.stat==TSC_STARTPENDING)
                {
                    emit Current_status("等待下载!",TSC_STARTPENDING);
                }
                else if(stTaskInfo.stat==TSC_STOPPENDING)
                {
                    emit Current_status("停止等待!",TSC_STARTPENDING);
                }
//                qDebug().noquote()<<QString("\n state              : %1 "
//                                            "\n fail_code          : %2"
//                                            "\n nTotalSize         : %3"
//                                            "\n nTotalDownload     : %4"
//                                            "\n fPercent           : %5"
//                                            "\n nSrcTotal          : %6"
//                                            "\n nSrcUsing          : %7"
//                                            "\n nSpeed             : %8"
//                                            "\n szFilename         : %9"
//                                            "\n szSavePath         : %10"
//                                            "\n IsCreatingFile     : %11"
//                                            "\n bIsOriginUsable    : %12 \n\n")
//                                     .arg(stateStr)
//                                     .arg(stTaskInfo.fail_code)
//                                     .arg(QString::number(stTaskInfo.nTotalSize,10))
//                                     .arg(QString::number(stTaskInfo.nTotalDownload,10))
//                                     .arg(QString::number(stTaskInfo.fPercent))
//                                     .arg(stTaskInfo.nSrcTotal)
//                                     .arg(stTaskInfo.nSrcUsing)
//                                     .arg(stTaskInfo.nSpeed)
//                                     .arg(QString::fromWCharArray(stTaskInfo.szFilename))
//                                     .arg(QString::fromWCharArray(stTaskInfo.szReserved0))
//                                     .arg(stTaskInfo.IsCreatingFile?"TRUE":"FALSE")
//                                     .arg(stTaskInfo.bIsOriginUsable?"TRUE":"FALSE")
//                                    ;
                //! 1秒查询一次
                }
            msleep(1000);
        }

    }
    catch (QString error) {
        ISuccessed=false;
        Error="异常信息 :"+error;
    }
    catch (...) {}
    qDebug()<<"thunderWrapper unInit-->";
    thunderWrapper->unInit();
    //! 清除连接
    delete thunderWrapper;
    thunderWrapper=nullptr;
    emit IsStart(true);
}

如图所示:
下载在网上找到系统镜像文件时,ThunderOpenSDK下载速度更快, 能稳定到9mb/s左右,而通过原生的QNetworkReply下载最高在5Mb/s左右。
请添加图片描述


ThunderOpenSDK 下载问题

ThunderOpenSDK 无法下载包含重定向跳转的下载链接,
正当我打算整体改用ThunderOpenSDK下载时,我突然发现ThunderOpenSDK 无法下载项目中的资源文件,换成其他网上找的资源文件又能正常下载,
测试多次发现ThunderOpenSDK只能下载直接指向下载资源的链接,
包含重定向跳转的下载链接下载不了!
无解,果断放弃,还是改用调用Aria2下载!
不过一般的下载ThunderOpenSDK库也完全够用了。

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

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

相关文章

Chrome谷歌浏览器加载ActiveX控件之allWebDesktop控件介绍

背景 allWebDesktop控件是一款方便用户在线打开各类文档的OA办公控件。它设计比较轻巧&#xff0c;充分利用计算机程序资源打开文档&#xff0c;并将程序窗口嵌入到allWebDesktop控件区域内&#xff0c;从而实现浏览器内打开各类文档效果。 allWebPlugin中间件是一款为用户提供…

【工具】Charles对360浏览器抓包抓包

Charles 和 switchy sharp 配合&#xff0c;可以对 Chrome 进行抓包也可以配合对360安全浏览器抓包。 本文以Windows 电脑中的配置为例&#xff0c;介绍如何实现抓包。&#xff08;Mac中操作基本一致&#xff09; 1.安装Charles 可根据自己的电脑下载对应的版本&#xff1a;…

【C++初阶】模版入门看这一篇就够了

文章目录 1. 泛型编程2. 函数模板2. 1 函数模板概念2. 2 函数模板格式2. 3 函数模板的原理2. 4 函数模板的实例化2. 5 模板参数的匹配原则2. 6 补充&#xff1a;使用调试功能观察函数调用 3. 类模板3 .1 类模板的定义格式3. 2 类模板的实例化 1. 泛型编程 在C语言中&#xff0…

【JavaEE初阶】网络原理—关于TCP协议值滑动窗口与流量控制,进来看看吧!!!

前言 &#x1f31f;&#x1f31f;本期讲解关于TCP协议的重要的机制“连接的建立和断开”~~~ &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 &#x1f525; 你的点赞就是小编不断更新的最大动力 &#x1…

5. STM32之TIM实验--输出比较(PWM输出,电机,四轴飞行器,智能车,机器人)--(实验5:PWM驱动直流电机)

作者:Whappy,日期:2024.10.29,决战STM32 直流电机的控制就比较简单了,只有数据线和地线,正接正转,反接反转,为了方便,本实验采用H桥电路来控制电机的正反转,H桥电路也很简单,就是4个MOS管构成的2路推挽输出电路. 注:基本上大功率器件,单片机基本上是无法驱动的,都是要靠一部分…

家用wifi的ip地址固定吗?换wifi就是换ip地址吗

在探讨家用WiFi的IP地址是否固定&#xff0c;以及换WiFi是否就意味着换IP地址这两个问题时&#xff0c;我们首先需要明确几个关键概念&#xff1a;IP地址、家用WiFi网络、以及它们之间的相互作用。 一、家用WiFi的IP地址固定性 家用WiFi环境中的IP地址通常涉及两类&#xff1a…

Python——自动化发送邮件

在数字化时代&#xff0c;电子邮件是商务沟通和个人联络的重要工具。自动化邮件发送可以节省时间&#xff0c;提高效率。Python&#xff0c;作为一种强大且灵活的编程语言&#xff0c;提供了多种库来支持邮件的自动化发送。本文将详细介绍如何使用Python的smtplib和email库来编…

DRC-20开发指南:新一代区块链代币标准

区块链技术自比特币诞生以来&#xff0c;迅速发展成为全球科技与金融领域的创新中心。随着区块链技术的普及&#xff0c;数字代币作为一种新兴的数字资产类别&#xff0c;逐渐为更多人所熟知。从ERC-20到BRC-20&#xff0c;代币标准的演进一直在推动着区块链生态系统的创新与发…

从零开始的JavaScript基础!

目录 一、JavaScript 的概述 二、如何在HTML页面中使用JS &#xff08;一&#xff09;、行内式 &#xff08;二&#xff09;、内嵌式 &#xff08;三&#xff09;、外链式 &#xff08;四&#xff09;、基本执行顺序 1.从上到下线性执行&#xff1a; 2.阻塞行为&#x…

“格格不入”的星瑞东方曜,燃油市场有麻烦了

文/王俣祺 导语&#xff1a;在新能源汽车蓬勃发展的当下&#xff0c;吉利近日推出的星瑞东方曜可以说有些“格格不入”了。那么&#xff0c;这款被称为“10万以内唯一选择”的新车&#xff0c;究竟带来了哪些新变化&#xff0c;又会给燃油市场中苦苦坚持的“战友们”带来多大的…

【ACM出版,EI稳定检索,九大高校联合举办, IEEE Fellow支持】2024年计算机视觉与艺术研讨会(CVA 2024)

在线投稿&#xff1a;学术会议-学术交流征稿-学术会议在线-艾思科蓝 2024年计算机视觉与艺术国际学术会议&#xff08;CVA 2024&#xff09;作为2024年人工智能、数字媒体技术与交互设计国际学术会议&#xff08;ICADI 2024)的分会。此次大会旨在汇聚全球在计算机视觉与艺术…

【MySql】-0.1、Unbunt20.04二进制方式安装Mysql5.7和8.0

1、下载Mysql二进制报&#xff08;选择Linux的通用版本&#xff09; mysql官网地址&#xff1a;https://downloads.mysql.com/archives/community/ wget https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.26-linux-glibc2.12-x86_64.tar wget https://downloads.…

H7-TOOL的LUA小程序教程第16期:脉冲测量,4路PWM,多路GPIO和波形打印(2024-10-25, 更新完毕)

LUA脚本的好处是用户可以根据自己注册的一批API&#xff08;当前TOOL已经提供了几百个函数供大家使用&#xff09;&#xff0c;实现各种小程序&#xff0c;不再限制Flash里面已经下载的程序&#xff0c;就跟手机安装APP差不多&#xff0c;所以在H7-TOOL里面被广泛使用&#xff…

【Cri-Dockerd】安装cri-dockerd

cri-dockerd的作用&#xff1a; 在k8s1.24之前。k8s会通过dockershim来调用docker进行容器运行时containerd&#xff0c;并且会自动安装dockershim&#xff0c;但是从1.24版本之前k8s为了降低容器运行时的调用的复杂度和效率&#xff0c;直接调用containerd了&#xff0c;并且…

java实现的音视频格式转化器

一、前言 最近写了一款图形界面版的音视频格式转化器&#xff0c;可以实现将多种视频之间进行转化&#xff0c;非常好用&#xff0c;如将AVI转换为&#xff0c;TS&#xff0c;FLV&#xff0c;MP4等。音频可将MP3转成WAV。 二、实现 1.需引入相关maven依赖。 <!-- 核心包 -…

Java知识巩固(十二)

I/O JavaIO流了解吗&#xff1f; IO 即 Input/Output&#xff0c;输入和输出。数据输入到计算机内存的过程即输入&#xff0c;反之输出到外部存储&#xff08;比如数据库&#xff0c;文件&#xff0c;远程主机&#xff09;的过程即输出。数据传输过程类似于水流&#xff0c;因…

1.3 面向对象 C++面试问题

1.3.1 简述一下什么是面向对象,面向对象与面向过程的区别 什么是面向对象 面向对象&#xff08;Object-Oriented Programming&#xff0c;OOP&#xff09;是一种编程范式&#xff0c;它通过将现实世界中的实体抽象为“对象”来组织代码。面向对象编程关注对象及其交互&#x…

Visual Studio Code

代码自动保存 打开设置搜索auto save&#xff0c;设置为afterDelay 设置延迟时间&#xff0c;单位是毫秒 启用Ctrl鼠标滚轮对字体进行缩放 搜索Mouse Wheel Zoom&#xff0c;把该选项勾选上即可 Python插件 运行和调试Python

Hash表算法

哈希表 理论知识&#xff08;本文来自于代码随想录摘抄&#xff09;什么是哈希常见的三种哈希结数组&#xff1a;set:map:其他常用方法或者技巧&#xff08;自己总结的&#xff09; 练习题和讲解有效的字母移位词349. 两个数组的交集1. 两数之和454. 四数相加 II15. 三数之和 总…

广泛的四款录屏工具专业软件解析!!!

当代社会的进步&#xff0c;电脑、手机等数码产品的普及&#xff0c;改变了我们的沟通形式&#xff0c;只需要动动手指&#xff0c;就能实现视频连接&#xff0c;影像播放等。有时候就需要我们录屏留存。在市面上的录屏软件种类繁多&#xff0c;从简洁易用的小工具到功能丰富的…