C++ 使用CURL开源库实现Http/Https的get/post请求进行字串和文件传输

CURL开源库介绍

CURL 是一个功能强大的开源库,用于在各种平台上进行网络数据传输。它支持众多的网络协议,像 HTTP、HTTPS、FTP、SMTP 等,能让开发者方便地在程序里实现与远程服务器的通信。
CURL 可以在 Windows、Linux、macOS 等多种操作系统上使用;
CURL 支持多种网络协议,能处理复杂的网络请求,如设置请求头、处理 cookies、上传和下载文件等。
使用前,编译CURL 源码,生成动态库,引入时包括头文件一起,网上也有别人已经编译好的现成的库可以下载使用。
CURL的头文件
生成的库:
在这里插入图片描述
在你要使用的项目里加上curl的头文件

#include <curl\curl.h>

这下你就可以使用CURL里的接口完成功能了。

CURL常用的接口说明:

  • 初始化与清理相关的接口:
  1. curl_easy_init()
    功能:创建并初始化一个新的 CURL 句柄,用于后续的网络操作。这个句柄就像一个会话的载体,后续的请求设置和执行都围绕它展开。
    返回值:成功时返回一个指向新创建的 CURL 句柄的指针;失败则返回 NULL。
  2. curl_easy_cleanup(CURL *handle)
    功能:释放 CURL 句柄占用的所有资源,包括内存、网络连接等。在使用完 CURL 句柄后,必须调用此函数以避免资源泄漏。
    参数:handle 是之前通过 curl_easy_init() 得到的 CURL 句柄。
  • 请求选项设置相关的接口:
  1. curl_easy_setopt(CURL *handle, CURLoption option, …)
    功能:设置 CURL 句柄的各种选项,这些选项可以控制请求的各个方面,如请求的 URL、请求方法、请求头、回调函数等。
    参数:
    handle:CURL 句柄。
    option:CURLoption 类型的常量,指定要设置的选项。
    可变参数:根据不同的 option,需要传入相应的参数值。
    常用 option 有:
    CURLOPT_URL:设置请求的 URL。
    CURLOPT_POST:将请求方法设置为 POST。
    CURLOPT_HTTPHEADER:设置请求头。
    CURLOPT_POSTFIELDS:设置 POST 请求的数据。
  2. curl_slist_append(struct curl_slist *list, const char *string)
    功能:用于构建一个链表来存储请求头信息。每次调用该函数可以将一个新的请求头字符串添加到链表中。
    参数:
    list:指向 curl_slist 链表的指针,如果是第一次添加,可传入 NULL。
    string:要添加的请求头字符串,格式为 Header-Name: Header-Value。
    返回值:返回更新后的链表指针。
  • 回调函数设置相关的接口:
  1. CURLOPT_WRITEFUNCTION 和 CURLOPT_WRITEDATA
    功能:CURLOPT_WRITEFUNCTION:设置一个回调函数,当服务器返回响应数据时,CURL 会调用该回调函数来处理响应数据。
    CURLOPT_WRITEDATA:传递一个用户自定义的指针给回调函数,用于在回调函数中存储或处理数据。
  2. CURLOPT_READFUNCTION 和 CURLOPT_READDATA
    功能:CURLOPT_READFUNCTION:设置一个回调函数,用于在发送数据时从用户提供的数据源中读取数据。
    CURLOPT_READDATA:传递一个用户自定义的指针给回调函数,用于标识数据源。
  • 多线程与异步操作相关的接口:
  1. curl_multi_init()
    功能:初始化一个 CURLM 句柄,用于多线程或异步的网络操作。该句柄可以管理多个 CURL 句柄,实现并发请求。
    返回值:成功时返回一个新的 CURLM 句柄指针;失败返回 NULL。
  2. curl_multi_add_handle(CURLM *multi_handle, CURL *easy_handle)
    功能:将一个 CURL 句柄添加到 CURLM 句柄管理的句柄列表中,以便进行并发处理。
    参数:
    multi_handle:CURLM 句柄。
    easy_handle:要添加的 CURL 句柄。
  3. curl_multi_perform(CURLM *multi_handle, int *still_running)
    功能:在 CURLM 句柄管理的所有 CURL 句柄上执行网络操作。该函数会尝试处理尽可能多的请求,并返回仍在运行的请求数量。
    参数:
    multi_handle:CURLM 句柄。
    still_running:指向一个整数的指针,用于存储仍在运行的请求数量。
  4. curl_multi_remove_handle(CURLM *multi_handle, CURL *easy_handle)
    功能:从 CURLM 句柄管理的句柄列表中移除一个 CURL 句柄。
    参数:
    multi_handle:CURLM 句柄。
    easy_handle:要移除的 CURL 句柄。
  5. curl_multi_cleanup(CURLM *multi_handle)
    功能:释放 CURLM 句柄占用的所有资源。在使用完 CURLM 句柄后,必须调用此函数进行清理。
    参数:multi_handle 是 CURLM 句柄。

接口流程使用:

简单的同步调用模式的使用流程:

  1. 调用curl_global_init()初始化libcurl ;
  2. 调用curl_easy_init()函数得到 easy;
  3. interface型指针 调用curl_easy_setopt()设置传输选项;
  4. 根据curl_easy_setopt()设置的传输选项,实现回调函数以完成用户特定任务;
  5. 调用curl_easy_perform()函数完成传输任务,返回错误码 ;
  6. 调用curl_easy_cleanup()释放内存;
  7. 调用curl_global_cleanup() (可以不用调用);

在整过过程中设置curl_easy_setopt()参数是最关键的,了解相关参数及对应作用很重要。

举例说明CURL的调用实现

//http回调写函数
static size_t   CurlWriteBuffer(char *buffer, size_t size, size_t nmemb, std::string* stream)
{//第二个参数为每个数据的大小,第三个为数据个数,最后一个为接收变量size_t sizes = size*nmemb;if(stream == NULL) return 0;stream->append(buffer,sizes);return sizes;
}//http发送封装
int  HttpClient::posturl(std::string& msg,	std::string& url, bool IsSSL)
{CURL* pCurl=NULL;        //一个libcurl的handleCURLcode res;            //返回状态码std::string response;    //返回信息curl_global_init(CURL_GLOBAL_ALL);      //全局初始化pCurl = curl_easy_init();                //创建一个handle//设置请求头struct  curl_slist* pHeader = NULL;//传json格式,字符编码为utf8header_ = curl_slist_append(pHeader ,"Content-Type: application/json;charset=utf-8");//添加请求头到handlecurl_easy_setopt(pCurl, CURLOPT_HTTPHEADER, pHeader );//设置URLcurl_easy_setopt(pCurl, CURLOPT_URL, url.c_str());  CURLOPT_WRITEFUNCTION 将后继的动作交给write_data函数处理curl_easy_setopt(pCurl,CURLOPT_POSTFIELDS,msg.c_str());            //post请求消息数据    curl_easy_setopt(pCurl,CURLOPT_POSTFIELDSIZE,msg.length());        //消息长度curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, CurlWriteBuffer);   //回调函数curl_easy_setopt(pCurl,CURLOPT_WRITEDATA,&response);               //数据接收变量curl_easy_setopt(pCurl,CURLOPT_TIMEOUT,m_settinginfo.m_http_timeout);  //连接超时时间//不支持ssl验证if(m_settinginfo.m_ssl == 0){curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, 0);//设定为不验证证书和HOSTcurl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYHOST, 0);}else{// 配置 https 请求所需证书if (m_settinginfo.m_ssl == 1)    //ssl单向验证,不验证服务器{curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, 0L);		}else{//双向验证curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, 1L);curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYHOST, 0);curl_easy_setopt(pCurl,CURLOPT_CAINFO,ca_info.ca_path.c_str()); }//设置客户端信息curl_easy_setopt(pCurl, CURLOPT_SSLCERT, ca_info.client_cert_path.c_str());curl_easy_setopt(pCurl,CURLOPT_SSLCERTTYPE,"PEM");  curl_easy_setopt(pCurl, CURLOPT_SSLKEY, ca_info.client_key_path.c_str());curl_easy_setopt(pCurl,CURLOPT_SSLKEYTYPE,"PEM"); //如果客户端证书密钥使用密码加密,设置加密密码//curl_easy_setopt(pCurl, CURLOPT_KEYPASSWD, "your_key_password");}//执行http连接res = curl_easy_perform(pCurl);//清除消息头curl_slist_free_all(pHeader);//清除handlecurl_easy_cleanup(pCurl);return 0;
}

再看一段完整的CURL封装成get,post等形式,进行字串传输和文件上传的请求,可以直接拿去使用。

//Http的Get请求
int HttpClient::ExecuteGetRequestCURL(const char* strUrl, const char* pszGet, const char* pszCookie, int nTimeOut)
{CURLcode res;m_strResponse = "";struct curl_slist* headers = NULL;CURL* curl = curl_easy_init();if (NULL == curl){return CURLE_FAILED_INIT;}std::string strOutData = strUrl;strOutData += pszGet;curl_easy_setopt(curl, CURLOPT_URL, strOutData.c_str());curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&m_strResponse);/*** 当多个线程都使用超时处理的时候,同时主线程中有sleep或是wait等操作。* 如果不设置这个选项,libcurl将会发信号打断这个wait从而导致程序退出。*/curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);//连接超时设置10s,数据请求超时设置60scurl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);curl_easy_setopt(curl, CURLOPT_TIMEOUT, nTimeOut);res = curl_easy_perform(curl);if (res != CURLE_OK)m_strResponse = "";curl_easy_cleanup(curl);return res;
}
//Http的post请求
int HttpClient::ExecutePostRequestCURL(const char* strUrl, const char* pszKey, const char* pszPost, const char* pszCookie, int nTimeOut)
{CURLcode res;m_strResponse = "";CURL* curl = curl_easy_init();if (NULL == curl){return CURLE_FAILED_INIT;}///struct curl_slist* headerlist = NULL;struct curl_httppost* formpost = NULL;struct curl_httppost* last = NULL;//headerlist = curl_slist_append(headerlist, "Content-Type:application/json;charset=UTF-8");//curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);res = curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "gzip, deflate, br");//设置CURLOPT_ACCEPT_ENCODING (7.21.8之前为CURLOPT_ENCODING )if (CURLE_OK != res){curl_easy_cleanup(curl);return CURLE_FAILED_INIT;}curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);if (CURLE_OK != res){curl_easy_cleanup(curl);return CURLE_FAILED_INIT;}curl_formadd(&formpost, &last, CURLFORM_PTRNAME, pszKey, CURLFORM_PTRCONTENTS, pszPost, CURLFORM_END);	//以这种方式上传可以避免特殊字符被改变if (CURLE_OK != res){curl_easy_cleanup(curl);return CURLE_FAILED_INIT;}curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);                     //构造post参数    if (CURLE_OK != res){curl_easy_cleanup(curl);return CURLE_FAILED_INIT;}/curl_easy_setopt(curl, CURLOPT_URL, strUrl);if (CURLE_OK != res){curl_easy_cleanup(curl);return CURLE_FAILED_INIT;}//curl_easy_setopt(curl, CURLOPT_POST, 1);//curl_easy_setopt(curl, CURLOPT_POSTFIELDS, pszPost);curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);if (CURLE_OK != res){curl_easy_cleanup(curl);return CURLE_FAILED_INIT;}curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);if (CURLE_OK != res){curl_easy_cleanup(curl);return CURLE_FAILED_INIT;}curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&m_strResponse);if (CURLE_OK != res){curl_easy_cleanup(curl);return CURLE_FAILED_INIT;}curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);if (CURLE_OK != res){curl_easy_cleanup(curl);return CURLE_FAILED_INIT;}if ((pszCookie != NULL)&&(strlen(pszCookie)>0)){ curl_easy_setopt(curl, CURLOPT_COOKIEFILE, (void *)&pszCookie);curl_easy_setopt(curl, CURLOPT_COOKIEJAR, (void *)&pszCookie);}//连接超时设置,数据请求超时设置curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);curl_easy_setopt(curl, CURLOPT_TIMEOUT, nTimeOut);res = curl_easy_perform(curl);if (res != CURLE_OK){m_strResponse = "";// 获取详细错误信息const char* szErr = curl_easy_strerror(res);fprintf(stderr, "curl_easy_perform() failed: %s\n", szErr);}// 清空curl_easy_cleanup(curl);// 释放表单curl_formfree(formpost);// 释放表头curl_slist_free_all (headerlist); return res;
}//https的Get请求
int HttpClient::ExecuteHttpsGetCURL(const std::string & strUrl, const char* pszGet, const char * pCaPath, int nTimeOut)
{CURLcode res;CURL* curl = curl_easy_init();if (NULL == curl){return CURLE_FAILED_INIT;}std::string strOutData = strUrl;strOutData += pszGet;curl_easy_setopt(curl, CURLOPT_URL, strOutData.c_str());curl_easy_setopt(curl, CURLOPT_HEADER, 0 ); curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&m_strResponse);curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);curl_easy_setopt(curl, CURLOPT_TIMEOUT, nTimeOut);if (NULL == pCaPath){curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);}else{curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true);curl_easy_setopt(curl, CURLOPT_CAINFO, pCaPath);}curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);//curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);//curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);//curl_easy_setopt(curl,CURLOPT_TRANSFERTEXT,1); res = curl_easy_perform(curl);if (res != CURLE_OK)m_strResponse = "";curl_easy_cleanup(curl);return res;
}//https的Post请求
int HttpClient::ExecuteHttpsPostCURL(const std::string& strUrl, const std::string& strKey, const std::string& strPost, const std::string& strCookie, const char* pCaPath, int nTimeOut)
{CURLcode res;CURL* curl = curl_easy_init();if (NULL == curl){return CURLE_FAILED_INIT;}///struct curl_slist* headers = NULL;struct curl_httppost* post = NULL;struct curl_httppost* last = NULL;curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "gzip, deflate, br");//设置CURLOPT_ACCEPT_ENCODING (7.21.8之前为CURLOPT_ENCODING )curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);curl_formadd(&post, &last, CURLFORM_PTRNAME, strKey.c_str(), CURLFORM_PTRCONTENTS, strPost.c_str(), CURLFORM_END);	//以这种方式上传可以避免特殊字符被改变curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);                     //构造post参数curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
// 	curl_easy_setopt(curl, CURLOPT_POST, 1);
// 	curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strPost.c_str());curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&m_strResponse);curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);//curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60*5);//curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60*5);if (strCookie.length()>0){curl_easy_setopt(curl, CURLOPT_COOKIEFILE, (void *)&strCookie);curl_easy_setopt(curl, CURLOPT_COOKIEJAR, (void *)&strCookie);}if (NULL == pCaPath){//curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);//curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);}else{//缺省情况就是PEM,所以无需设置,另外支持DER//curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM");curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true);curl_easy_setopt(curl, CURLOPT_CAINFO, pCaPath);}curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 20);curl_easy_setopt(curl, CURLOPT_TIMEOUT, nTimeOut);curl_easy_setopt(curl, CURLOPT_SSLVERSION, 3);res = curl_easy_perform(curl);curl_easy_cleanup(curl);return res;
}static size_t OnWriteData(void* buffer, size_t size, size_t nmemb, void* lpVoid)
{			std::string* str = reinterpret_cast<std::string*>(lpVoid);if (NULL == str || NULL == buffer){return -1;}char* pData =  reinterpret_cast<char*>(buffer);str->append(pData, size * nmemb);return nmemb;
}long HttpClient::GetRespone(char* pszResponse, long &lRespLen)
{long lRet = 0;if (m_strResponse.length() <= 0){lRet = 1;goto err;}if (pszResponse == NULL){lRespLen = m_strResponse.length();goto err;}if (lRespLen < m_strResponse.length()){lRet = 1;goto err;}memset(pszResponse, 0, lRespLen);memcpy(pszResponse, m_strResponse.c_str(), m_strResponse.length());lRespLen = m_strResponse.length();
err:return lRet;
}long HttpClient::GetFileNameAndExt(const std::string & strFilePath,std::string & strFileName,std::string & strFileExt)
{long lRet = 0;strFileExt = "";strFileName = "";int nPos = strFilePath.rfind('.');if (nPos == -1){lRet = CURLE_FAILED_INIT;	//文件不存在goto err;}strFileExt = strFilePath.substr(nPos+1, strFilePath.length());nPos = strFilePath.rfind('\\');if (nPos == -1){nPos = strFilePath.rfind('/');if (nPos == -1){strFileName = strFilePath;goto err;}}strFileName = strFilePath.substr(nPos+1, strFilePath.length());
err:return lRet;
}
//Http的post传文件请求
//strParamName是"bindingSeal",strParamVal值是对应的json包,strParamName2是"sealImages",strParamVal2值是图片名称
long HttpClient::HttpUploadFileCURL(LPCTSTR strUrl, const string& strFilePath, const string& strParamName, const string& strParamVal, const string& strParamName2, const string& strParamVal2, string& strResponse)
{CURL* curl;CURLcode res;long lRet = 0;std::string strFileName;std::string strFileExt;StringTool strTool;string strCRUL = strTool.WideToAsc(strUrl);lRet = GetFileNameAndExt(strFilePath, strFileName, strFileExt);if (lRet != 0)goto err;curl = curl_easy_init();struct curl_httppost* post = NULL;struct curl_httppost* last = NULL;if (curl == NULL){lRet = CURLE_FAILED_INIT;goto err;}curl_easy_setopt(curl, CURLOPT_URL, (char *)strCRUL.c_str());           //指定url//form-data key(path) 和 value(device_cover)curl_formadd(&post, &last, CURLFORM_PTRNAME, strParamName.c_str()/*"parma"*/, CURLFORM_PTRCONTENTS, strParamVal.c_str(), CURLFORM_END);curl_formadd(&post, &last, CURLFORM_PTRNAME,  strParamName2.c_str(), CURLFORM_FILE, strFilePath.c_str(),CURLFORM_FILENAME, strFileName.c_str(),CURLFORM_CONTENTTYPE,"image/png", CURLFORM_END);//curl_formadd(&post, &last, CURLFORM_PTRNAME,  strParamName2.c_str(), CURLFORM_FILE, strFilePath.c_str(),CURLFORM_FILENAME, strFileName.c_str(),CURLFORM_CONTENTTYPE,"image/PNG", CURLFORM_END);curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);                     //构造post参数    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData);          //绑定相应curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse);        //绑定响应内容的地址res = curl_easy_perform(curl);                          //执行请求if(res == 0){curl_easy_cleanup(curl);    lRet =  res;goto err;}else{lRet =  res;goto err;}lRet = res;err:return lRet;
}

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

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

相关文章

基础入门-网站协议身份鉴权OAuth2安全Token令牌JWT值Authirization标头

知识点&#xff1a; 1、网站协议-http/https安全差异&#xff08;抓包&#xff09; 2、身份鉴权-HTTP头&OAuth2&JWT&Token 一、演示案例-网站协议-http&https-安全测试差异性 1、加密方式 HTTP&#xff1a;使用明文传输&#xff0c;数据在传输过程中可以被…

07苍穹外卖之redis缓存商品、购物车(redis案例缓存实现)

课程内容 缓存菜品 缓存套餐 添加购物车 查看购物车 清空购物车 功能实现&#xff1a;缓存商品、购物车 效果图&#xff1a; 1. 缓存菜品 1.1 问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压…

DeepSeek-R1 本地大模型搭建对接API

DeepSeek-R1 在这里将学到很多知识 欢迎使用使用DeepSeek-R1本地大模型DeepSeek 的模型基础说明DeepSeek的本地 API 说明DeepSeek 本地模型搭建1、执行命令安装及测试 DeepSeek-R1 API接口调用当然&#xff0c;我们为了让用户更加便捷&#xff0c;我们把API 接口全部放到上面截…

250207-MacOS修改Ollama模型下载及运行的路径

在 macOS 上&#xff0c;Ollama 默认将模型存储在 ~/.ollama/models 目录。如果您希望更改模型的存储路径&#xff0c;可以通过设置环境变量 OLLAMA_MODELS 来实现。具体步骤如下&#xff1a; 选择新的模型存储目录&#xff1a;首先&#xff0c;确定您希望存储模型的目标目录路…

单片机之基本元器件的工作原理

一、二极管 二极管的工作原理 二极管是一种由P型半导体和N型半导体结合形成的PN结器件&#xff0c;具有单向导电性。 1. PN结形成 P型半导体&#xff1a;掺入三价元素&#xff0c;形成空穴作为多数载流子。N型半导体&#xff1a;掺入五价元素&#xff0c;形成自由电子作为多…

CNN 卷积神经网络处理图片任务 | PyTorch 深度学习实战

前一篇文章&#xff0c;学习率调整策略 | PyTorch 深度学习实战 本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started CNN 卷积神经网络 CNN什么是卷积工作原理深度学习的卷积运算提取特征不同特征核的效果比较卷积核感受野共享权重池化 示例源码 …

3.1 学习UVM中的uvm_component类分为几步?

文章目录 前言一、定义1.1 角色和功能&#xff1a;1.2 与其他UVM类的区别&#xff1a;1.3 主要属性和方法&#xff1a; 二、使用方法2.1 定义和实例化&#xff1a;2.2 生命周期管理&#xff1a;2.3 组件间通信&#xff1a; 三、何时使用3.1 使用场景3.2 适用组件3.3 与uvm_obje…

谷云科技RestCloud全面接入DeepSeek 开启智能新时代

在数字化转型的浪潮中&#xff0c;谷云科技始终走在数据集成与智能应用领域的前沿。近期&#xff0c;随着 DeepSeek 的火爆出圈&#xff0c;谷云科技紧跟技术趋势&#xff0c;对旗下两大核心产品 —— 数据集成软件 ETLCloud 和 AI Agent 智能体构建平台进行了重大升级&#xf…

Kafka 入门与实战

一、Kafka 基础 1.1 创建topic kafka-topics.bat --bootstrap-server localhost:9092 --topic test --create 1.2 查看消费者偏移量位置 kafka-consumer-groups.bat --bootstrap-server localhost:9092 --describe --group test 1.3 消息的生产与发送 #生产者 kafka-cons…

【个人开发】macbook m1 Lora微调qwen大模型

本项目参考网上各类教程整理而成&#xff0c;为个人学习记录。 项目github源码地址&#xff1a;Lora微调大模型 项目中微调模型为&#xff1a;qwen/Qwen1.5-4B-Chat。 去年新发布的Qwen/Qwen2.5-3B-Instruct同样也适用。 微调步骤 step0: 环境准备 conda create --name fin…

了解Linux 中 make 与 Makefile

目录 一、为什么开发者需要构建工具&#xff1f; 二、make/Makefile 1. Makefile基本规则 2.清理项目 三、make的工作原理 一、为什么开发者需要构建工具&#xff1f; 在软件开发中&#xff0c;我们经常面临这样的场景&#xff1a;一个项目包含数十个源代码文件&#xff…

win11右击显示全部

正常&#xff1a; 输入&#xff1a; reg.exe add "HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32" /f /ve 重启或刷新进程 刷新&#xff1a; taskkill /f /im explorer.exe & start explorer.exe 成功&#xff1a;

Redis基础--常用数据结构的命令及底层编码

零.前置知识 关于时间复杂度,按照以下视角看待. redis整体key的个数 -- O(N)当前key对应的value中的元素个数 -- O(N)当前命令行中key的个数 -- O(1) 一.string 1.1string类型常用命令 1.2string类型内部编码 二.Hash 哈希 2.1hash类型常用命令 2.2hash类型内部编码 2.3ha…

React 设计模式:实用指南

React 提供了众多出色的特性以及丰富的设计模式&#xff0c;用于简化开发流程。开发者能够借助 React 组件设计模式&#xff0c;降低开发时间以及编码的工作量。此外&#xff0c;这些模式让 React 开发者能够构建出成果更显著、性能更优越的各类应用程序。 本文将会为您介绍五…

Unity扩展编辑器使用整理(一)

准备工作 在Unity工程中新建Editor文件夹存放编辑器脚本&#xff0c; Unity中其他的特殊文件夹可以参考官方文档链接&#xff0c;如下&#xff1a; Unity - 手册&#xff1a;保留文件夹名称参考 (unity3d.com) 一、菜单栏扩展 1.增加顶部菜单栏选项 使用MenuItem&#xff…

Vue3+codemirror6实现公式(规则)编辑器

实现截图 实现/带实现功能 插入标签 插入公式 提示补全 公式验证 公式计算 需要的依赖 "codemirror/autocomplete": "^6.18.4","codemirror/lang-javascript": "^6.2.2","codemirror/state": "^6.5.2","cod…

4.PPT:日月潭景点介绍【18】

目录 NO1、2、3、4​ NO5、6、7、8 ​ ​NO9、10、11、12 ​ 表居中或者水平/垂直居中单元格内容居中或者水平/垂直居中 NO1、2、3、4 新建一个空白演示文稿&#xff0c;命名为“PPT.pptx”&#xff08;“.pptx”为扩展名&#xff09;新建幻灯片 开始→版式“PPT_素材.doc…

开源项目介绍-词云生成

开源词云项目是一个利用开源技术生成和展示词云的工具或框架&#xff0c;广泛应用于文本分析、数据可视化等领域。以下是几个与开源词云相关的项目及其特点&#xff1a; Stylecloud Stylecloud 是一个由 Maximilianinir 创建和维护的开源项目&#xff0c;旨在通过扩展 wordclou…

Redis双写一致性(数据库与redis数据一致性)

一 什么是双写一致性&#xff1f; 当修改了数据库&#xff08;MySQL&#xff09;中的数据&#xff0c;也要同时更新缓存&#xff08;redis&#xff09;中的数据&#xff0c;缓存中的数据要和数据库中的数据保持一致 双写一致性&#xff0c;根据业务对时间上的要求&#xff0c;…

C32.【C++ Cont】静态实现双向链表及STL库的list

目录 1.知识回顾 2.静态实现演示图 3.静态实现代码 1.初始双向链表 2.头插 3.遍历链表 4.查找某个值 4.任意位置之后插入元素 5.任意位置之前插入元素 6.删除任意位置的元素 4.STL库的list 1.知识回顾 96.【C语言】数据结构之双向链表的初始化,尾插,打印和尾删 97.【C…