Windows内核开发

news/2024/4/28 8:09:52/文章来源:https://blog.csdn.net/weixin_42284219/article/details/130043340

Windows内核开发

Unit01对话框

对话框是一种很特殊的窗口,体现在消息的处理上

//普通窗口处理消息:自定义函数调用缺省消息处理函数
WndProc(...){...DefWindowProc(...);
}//对话框窗口处理消息:缺省函数调用自定义函数
缺省函数(...){...自定义函数(...);....
}

01对话框原理

  • 对话框的分类
    • 模式对话框:当对话框显示时,会禁止本进程其他窗口和用户交互操作
    • 无模式对话框:在对话框显示后,其他窗口仍然可以和用户交互操作
  • 对话框基本使用
    • 1.对话框处理函数
    • 2.注册窗口类(不用程序员自己注册窗口类,系统已经注册好对话框的窗口类)
    • 3.创建对话框
    • 4.对话框的关闭
  • 对话框窗口处理函数(并非真正的对话框窗口处理函数)
INT CALLBACK DialogProc(//函数名自定义HWND hwndDlg, //窗口句柄UINT uMsg, //消息IDWPARAM wParam, //消息参数LPARAM lParam//消息参数
);
//返回TRUE,缺省处理函数不需要处理
//返回FaLSE,交给缺省处理函数处理
//不需要调用缺省对话框处理函数

在这里插入图片描述

02模式对话框

  • 创建模式对话框
int DialogBox(HINSTANCE hInstance,//应用程序实例句柄LPCTSTR lpTemplate,//对话框资源IDHWND hWndParent, //对话框窗口DLGPROC lpDialogFunc//自定义函数
); 
//DialogBox是一个阻塞函数,只有当对话框关闭后,才会返回,继续执行后续代码
//返回值是通过EndDialog设置
  • 关闭对话框
BOOL EndDialog(HWND hDlg,//关闭的对话框窗口句柄int nResult//关闭的返回值
); 
//关闭模式对话框,只能适应EndDialog,不能使用DestoryWindow等函数
//nResult是DialogBox函数退出时的返回值
  • 对话框的消息:WM_INITDIALOG对话框创建之后显示之前,通过对话框窗口处理函数,可以完成自己的初始化相关的操作

示例代码:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

#include <windows.h>
#include "resource.h"HINSTANCE g_hInstance = 0;INT CALLBACK DlgProc(HWND hWndlg,UINT msgID,WPARAM wParam,LPARAM lParam){switch(msgID){case WM_INITDIALOG:MessageBox(hWndlg, "WM_INITDIALOG", "Infor", MB_OK);break;case WM_CREATE://为了验证对话框没有这个消息MessageBox(hWndlg, "WM_CREATE", "Infor", MB_OK);break;case WM_SYSCOMMAND:if(wParam == SC_CLOSE){//销毁对话框EndDialog(hWndlg,100);//两个功能销毁知名的对话框、解除DialogBox的阻塞//DestroyWindow(hWndlg);//只是销毁对话框,但是并没有解除解除DialogBox的阻塞,所以不能用}break;}return FALSE;//将消息交给真正的对话框窗口系统处理函数的后续代码帮我们处理
}void OnCommand(HWND hWnd, WPARAM wParam){switch(LOWORD(wParam)){case ID_MODEL:int nRet = DialogBox(g_hInstance, (char*)IDD_DIALOG1,hWnd,DlgProc);if(nRet == 100){MessageBox(hWnd, "successful", "Infor", MB_OK);}break;}
}
//窗口处理函数(自定义,处理函数)
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,WPARAM wParam,LPARAM lParam)
{switch(msgID){case WM_COMMAND:OnCommand(hWnd, wParam);break;case WM_DESTROY:PostQuitMessage(0);//可以使GetMessage函数返回0break;}return DefWindowProc(hWnd, msgID, wParam, lParam);
}
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns,LPSTR lpCmdLine,int nCmdShow)
{g_hInstance = hIns;//注册窗口类WNDCLASS wc = {0};wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.hCursor = NULL;wc.hIcon = NULL;wc.hInstance = hIns;wc.lpfnWndProc = WndProc;wc.lpszClassName = "Main";//挂载菜单资源wc.lpszMenuName = (char*)IDR_MENU1;wc.style = CS_HREDRAW|CS_VREDRAW;RegisterClass(&wc);//将以上所有赋值全部写入操作系统内核//在内存创建窗口HWND hWnd = CreateWindowEx(0,"Main","window",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hIns,NULL);//显示窗口ShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);//消息循环MSG nMsg = {0};while(GetMessage(&nMsg,NULL,0,0)){TranslateMessage(&nMsg);DispatchMessage(&nMsg);//将消息交给窗口处理函数来处理}return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

03无模式对话框

  • 创建无模式对话框
HWND CreateDialog(HINSTANCE hInstance,//应用程序实例句柄LPCTSTR lpTemplate, //模板资源IDHWND hWndParent,//父窗口DLGPROC lpDialogFunc//自定义函数
); 
//非阻塞函数,创建成功返回窗口句柄,需要使用ShowWindow函数显示对话框
BOOL ShowWindow(HWND hWnd,int nCmdShow
); 

在这里插入图片描述

  • 对话框的关闭
    • 关闭时使用DestroyWindow销毁窗口哦,不能使用EndDialog关闭对话框
BOOL DestroyWindow(HWND hWnd); 

示例代码:

#include <windows.h>
#include "resource.h"HINSTANCE h_gInstance = 0;INT CALLBACK DlgProc(HWND hWndlg,UINT msgID,WPARAM wParam,LPARAM lParam){switch(msgID){case WM_SYSCOMMAND:if(wParam == SC_CLOSE)DestroyWindow(hWndlg);break;}return FALSE;
}void OnCommand(HWND hWnd,WPARAM wParam){switch(LOWORD(wParam)){case ID_UNMODEL:HWND hWndlg = CreateDialog(h_gInstance, (char*)IDD_DIALOG1, hWnd, DlgProc);ShowWindow(hWndlg, SW_SHOWNORMAL);break;}
}//窗口处理函数(自定义,处理函数)
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,WPARAM wParam,LPARAM lParam)
{switch(msgID){case WM_COMMAND:OnCommand(hWnd, wParam);break;case WM_DESTROY:PostQuitMessage(0);//可以使GetMessage函数返回0break;}return DefWindowProc(hWnd, msgID, wParam, lParam);
}
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns,LPSTR lpCmdLine,int nCmdShow)
{h_gInstance = hIns;//注册窗口类WNDCLASS wc = {0};wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.hCursor = NULL;wc.hIcon = NULL;wc.hInstance = hIns;wc.lpfnWndProc = WndProc;wc.lpszClassName = "Main";wc.lpszMenuName = (char*)IDR_MENU1;wc.style = CS_HREDRAW|CS_VREDRAW;RegisterClass(&wc);//将以上所有赋值全部写入操作系统内核//在内存创建窗口HWND hWnd = CreateWindowEx(0,"Main","window",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hIns,NULL);//显示窗口ShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);//消息循环MSG nMsg = {0};while(GetMessage(&nMsg,NULL,0,0)){TranslateMessage(&nMsg);DispatchMessage(&nMsg);//将消息交给窗口处理函数来处理}return 0;
}

Unit02静态库

01静态库特点

  • 运行不存在
  • 静态库源码被链接到调用程序中
  • 目标程序的归档(就是程功能已经封装好直接来调用就行)

02C语言静态库

  • C静态库的创建
    • 创建一个静态库项目
    • 添加库程序,源文件适应C文件
  • C静态库的使用
    • 库路径设置:可以使用pragma关键字设置
    • #pragma comment(lib,"../lib/clib.lib")
      在这里插入图片描述在这里插入图片描述在这里插入图片描述

在这里插入图片描述
![在这里插入图片描述](https://img-blog.csdnimg.cn/002a6bcdc7964dcaaf19f2d7ac1ed96a.png#pic_center
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

在这里插入图片描述在这里插入图片描述

//通知链接器到哪抓源码
#pragma comment(lib, "../Debug/Clib.lib")int main(void){int sum, sub;sum = Clib_add(5,3);sub = Clib_sub(5,3);printf("sum=%d, sub=%d\n", sum, sub);getchar();return 0;
}

03C++语言静态库

  • C++静态库的创建
    • 创建一个静态库项目
    • 添加程序库,源文件使用CPP文件
  • C++静态库的使用
    • 库路径设置:可以使用pragma关键字设置
    • #progma comment(lib, "../lib/cpplib.lib")
      在这里插入图片描述
      在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include <iostream>using namespace std;//添加函数声明
int CPPlib_add(int add1, int add2);
int CPPlib_sub(int sub1, int sub2);
//给连接器看的
#pragma comment(lib, "../Debug/CPPlib.lib")int main(){int sum = CPPlib_add(5, 4);int sub = CPPlib_sub(5, 4);cout << "sum=" << sum << ".sub=" << sub << endl;getchar();return 0;
}
  • 使用C++调C语言的静态库
#include <iostream>using namespace std;//添加函数声明
int CPPlib_add(int add1, int add2);
int CPPlib_sub(int sub1, int sub2);
//给连接器看的
#pragma comment(lib, "../Debug/CPPlib.lib")//使用C语言的Clib.lib库函数,extern "C"防止c++编译器进行换名操作
extern "C" int Clib_add(int add1, int add2);
extern "C" int Clib_sub(int sub1, int sub2);
#pragma comment(lib, "../Debug/Clib.lib")int main(){int sum = CPPlib_add(5, 4);//?CPPlib_add@@YAHHH@Zint sub = CPPlib_sub(5, 4);//?CPPlib_sub@@YAHHH@Zcout << "sum=" << sum << ".sub=" << sub << endl;sum = Clib_add(5,3);//Clib_addsub = Clib_sub(5,3);//Clib_subcout << "sum=" << sum << ".sub=" << sub << endl;getchar();return 0;
}

在这里插入图片描述

Unit03动态库

01动态库的特点

  • 动态库的特点
    • 运行时独立存在
    • 源码不会链接到执行程序
    • 使用加载(使用动态库必须使动态库执行,就是让动态库进入内存)
  • 与静态库相比较
    • 由于静态库是将代码嵌入到使用程序中,多个程序使用时,会有多份代码,所以代码体积会增大。动态库的代码只需要一份,其他程序通过函数地址使用,所以代码体积小
    • 静态库发生变化后,新的代码需要重新链接嵌入到执行程序中,动态库发生变化后如果库中的函数的定义(或地址)未变化,其他使用DLL的程序不需要重新链接。

02动态库创建

  • 创建动态库项目
  • 添加库程序
  • 库程序导出:提供给使用者库中的函数信息(实际是导出的是动态库封装的函数的地址导出来,导出的地址在dll文件的文件头中)
    • 1.声明导出:使用_declspec(dllexport)导出函数
      • 注意:动态库编译链接后,也会有LIB文件,是作为动态库函数映射使用,与静态库不完全相同
    • 2.模块定义文件.def
      • 例如:LIBRARY DLLFunc//库
      • EXPORTS//库导出表
      • DLL_Mul @1//导出的函数
        在这里插入图片描述
        在这里插入图片描述
        在这里插入图片描述
        在这里插入图片描述
        在这里插入图片描述
        在这里插入图片描述
        在这里插入图片描述在这里插入图片描述

//_declspec(dllexport)加上这个是为了导出动态库函数
_declspec(dllexport) int CPPdll_add(int add1, int add2){return add1 + add2;
}_declspec(dllexport) int CPPdll_sub(int sub1, int sub2){return sub1 + sub2;
}_declspec(dllexport) int CPPdll_mul(int mul1, int mul2){return mul1 + mul2;
}

03动态库的使用

隐式链接(操作系统负责动态库执行)

  • 头文件和函数原型:可以在函数原型的声明前,增加_declspec(dllimport)
  • 导入动态库和LIB文件,#pragma comment(lib, "../Debug/CPPdll.lib")
  • 在程序中使用函数
  • 隐式链接的情况:dll文件可以存放在的路径:
    • 与执行文件同一个目录下(推荐使用这个路径下)
    • 当前工作目录(就是当前的项目目录下)
    • Windows目录(不建议放在系统目录下)
    • Windows/System32目录(不建议放在系统目录下)
    • Windows/System(不建议放在系统目录下)
    • 环境变量PATH指定目录(不建议放在系统路径下中,因为可以更改)
      在这里插入图片描述
      在这里插入图片描述在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
#include <iostream>using namespace std;
//声明函数
_declspec(dllimport) int CPPdll_add(int add1, int add2);
_declspec(dllimport) int CPPdll_sub(int sub1, int sub2);
_declspec(dllimport) int CPPdll_mul(int mul1, int mul2);//通知链接器到哪抓函数的 编号和dll文件名("CPPdll.dll")
#pragma comment(lib, "../Debug/CPPdll.lib")int main(){int sum = CPPdll_add(5,4);int sub = CPPdll_sub(5,4);int mul = CPPdll_mul(5,4);cout << "sum=" << sum << ",sub=" << sub << ",mul=" << mul << endl;system("pause");return 0;
}

显式链接(程序员自己负责使用动态库执行)

  • 定义函数指针类型typedef
  • 加载动态库(就是让动态进内存)
HMODULE LoadLibrary(LPCTSTR lpFileName//动态库文件名或全路径
);//返回DLL的实例句柄(HINSTANCE)
  • 获取函数真实地址
FARPROC GetProcAddress(HMODULE hModule,//DLL句柄LPCWSTR lpProcName//函数名称
); //成功返回函数地址
  • 使用函数
  • 卸载动态库
BOOL FreeLibrary(HMODULE hLibModule//DLL的实例句柄
); 

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

#include <windows.h>
#include <iostream>using namespace std;typedef int(*ADD)(int m, int n);
typedef int(*SUB)(int m, int n);
typedef int(*MUL)(int m, int n);int main(){HINSTANCE hDll = LoadLibrary("CPPdll.dll");cout << "hDll:" << hDll << endl;//ADD myAdd = (ADD)GetProcAddress(hDll, "CPPdll_add");ADD myAdd = (ADD)GetProcAddress(hDll, "?CPPdll_add@@YAHHH@Z");cout << "myAdd:" << myAdd << endl;int sum = myAdd(5,4);cout << "sum=" << sum << endl;//SUB mySub = (SUB)GetProcAddress(hDll, "CPPdll_sub");SUB mySub = (SUB)GetProcAddress(hDll, "?CPPdll_sub@@YAHHH@Z");cout << "mySub:" << mySub << endl;int sub = mySub(5,4);cout << "sub=" << sub << endl;//MUL myMul = (MUL)GetProcAddress(hDll, "CPPdll_mul");MUL myMul = (MUL)GetProcAddress(hDll, "?CPPdll_mul@@YAHHH@Z");cout << "myMul:" << myMul << endl;int mul = myMul(5,4);cout << "mul=" << mul << endl;FreeLibrary(hDll);system("pause");return 0;
}

为了使用不换名的函数名,重名生成导出动态库文件

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

#include <windows.h>
#include <iostream>using namespace std;typedef int(*ADD)(int m, int n);
typedef int(*SUB)(int m, int n);
typedef int(*MUL)(int m, int n);int main(){HINSTANCE hDll = LoadLibrary("CPPdll.dll");cout << "hDll:" << hDll << endl;ADD myAdd = (ADD)GetProcAddress(hDll, "CPPdll_add");//ADD myAdd = (ADD)GetProcAddress(hDll, "?CPPdll_add@@YAHHH@Z");cout << "myAdd:" << myAdd << endl;int sum = myAdd(5,4);cout << "sum=" << sum << endl;SUB mySub = (SUB)GetProcAddress(hDll, "CPPdll_sub");//SUB mySub = (SUB)GetProcAddress(hDll, "?CPPdll_sub@@YAHHH@Z");cout << "mySub:" << mySub << endl;int sub = mySub(5,4);cout << "sub=" << sub << endl;//MUL myMul = (MUL)GetProcAddress(hDll, "CPPdll_mul");MUL myMul = (MUL)GetProcAddress(hDll, "?CPPdll_mul@@YAHHH@Z");cout << "myMul:" << myMul << endl;int mul = myMul(5,4);cout << "mul=" << mul << endl;FreeLibrary(hDll);system("pause");return 0;
}

04 动态库中封装类

  • 在类名称前增加_declspec(dllexport)定义,例如:
class _declspec(dllexport) CMath{//...
};
  • 通常使用预编译开关切换类的导入导出定义,例如:
#ifdef DLLCLASS_EXPORTS
#define EXT_CLASS_declspec(dllexport)//DLL
#else
#define EXT_CLASS_declspec(dllimport)//使用者
#endif
class EXT_CLASS CMath{//...
};

注意:封装类动态库一般只要声明导出,而不用定义文件导出,因为导出类真正是导出类中封装的函数相对地址

示例:创建封装类的动态库
在这里插入图片描述在这里插入图片描述

在这里插入图片描述

#ifndef _DLLCLASS_H
#define _DLLCLASS_H#ifdef DLLCLASS_EXPORTS
#define EXT_CLASS _declspec(dllexport)
#else
#define EXT_CLASS _declspec(dllimport)
#endifclass EXT_CLASS CMath{
public:int Add(int add1, int add2);int Sub(int sub1, int sub2);
};#endif //_DLLCLASS_H

在这里插入图片描述

#define DLLCLASS_EXPORTS#include "ClassDll.h"int CMath::Add(int add1, int add2){return add1 + add2;
}int CMath::Sub(int sub1, int sub2){return sub1 - sub2;
}

在这里插入图片描述
在这里插入图片描述

示例:调用封装好的动态库
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include <iostream>
#include "../ClassDll/ClassDll.h"#pragma comment(lib, "../Debug/ClassDll.lib")using namespace std;int main(){CMath math;int sum = math.Add(5, 6);int sub = math.Sub(5, 6);cout << "sum=" << sum << ",sub=" << sub << endl;return 0;
}

在这里插入图片描述

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

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

相关文章

从繁琐的采集工作中解放出来,让拓客变得更高效

近年来&#xff0c;企业拓客发展越来越受到重视&#xff0c;但是拓客的过程中却面临着很多的挑战&#xff0c;其中最为繁琐的工作就是采集工作。采集工作不仅耗费大量的时间和精力&#xff0c;还容易出现误差和遗漏&#xff0c;影响到整个拓客的效率和质量。为了解决这个问题&a…

6.Swagger的实战使用

六.Swagger的实战使用 1.什么是swagger 2.swagger的基本使用 3.swagger实战使用 六.Swagger的实战使用 1.什么是swagger swagger是后端接口文档的生成并且提供ui界面进行测试过去用postman测试 缺点&#xff1a;需要自己写地址&#xff0c;如果项目变了需要自己更改 2.sw…

MySQL事务 【事务操作丨事务四大特性丨事务隔离级别丨事务原理】

在实际的开发过程中&#xff0c;一个业务操作如&#xff1a;转账&#xff0c;往往是要多次访问数据库才能完成的。转账是一个用户扣钱&#xff0c;另一个用户加钱。如果其中有一条 SQL 语句出现异常&#xff0c;这条 SQL 就可能执行失败。 事务是一组操作的集合&#xff0c;它…

计讯物联小型水库雨水情测报与大坝安全监测一体化解决方案,确保水库安全运行

方案背景 防洪治理工程是一项重大的民生工程&#xff0c;也是重大的生态工程。基于我国水灾频发的大背景下&#xff0c;小型水库作为防汛抗洪的重要基础设施&#xff0c;其雨水情测报与大坝安全监测是十分有必要的&#xff0c;不仅可为预防水灾、防汛决策提供大量可靠的数据和资…

深入浅出:理解 RPC 和 Dubbo 架构

简介 Apache Dubbo是一款高性能的Java RPC框架.其前身是阿里巴巴公司开源的一个高性能,轻量级的开源Java RPC框架,可以和Spring框架无缝集成. Dubbo 官网 RPC RPC介绍 Remote Procedure Call 远程过程调用,是分布式架构的核心,按响应方式分以下两种: 同步调用:客户端调用…

CAN通讯协议

1&#xff09; CAN介绍 a) 什么是CAN? b) CAN总线特点 c) CAN应用场景 2&#xff09;CAN物理层 a) CAN物理层特性 b) CAN收发器芯片介绍 3&#xff09;CAN协议层 a) CAN帧种类介绍 b) CAN数据帧介绍 c) CAN位时序介绍 d) CAN总线仲裁 a)、CAN介绍 CAN&#xff08;Controlle…

SpringBoot中配置文件加密及跨域支持

给application.properties文件中的某些值加密,比如数据库账号密码等. 引入依赖 <dependency><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-spring-boot-starter</artifactId><version>3.0.3</version> </dep…

并行分布式计算 并行计算机体系结构

文章目录并行分布式计算 并行计算机体系结构并行计算机结构模型SIMD 单指令多数据流PVP 并行向量处理机SMP 对称多处理机MPP 大规模并行处理机DSM 分布式共享存储多处理机COW 工作站集群总结并行计算机访存模型UMA 均匀存储访问模型NUMA 非均匀存储访问模型COMA 全高速缓存存储…

Nestjs实战干货-概况-控制器-Controller

Controller 控制器 控制器负责处理传入的请求并向客户返回响应。 一个控制器的目的是接收应用程序的特定请求。路由机制控制哪个控制器接收哪些请求。通常&#xff0c;每个控制器有一个以上的路由&#xff0c;不同的路由可以执行不同的动作。 为了创建一个基本的控制器&#…

【游戏逆向】加密坐标浅析

这个游戏里面坐标有很多种存放方式。 例如明文存放的DOUBLE&#xff0c;加密的各种类型。 我们不知道哪一个对于我们是有用的,哪一些只是辅助UI或则掉到LUA虚拟机坑里的数据。 那就根据作用大小来决定,一一尝试吧。 最好去找修改之后有效果的地址&#xff0c;当然只是本地&…

MySQL中count(1)和count(*)哪个性能好?

当我们对某一张表中的数据需要统计数量的时候&#xff0c;我们通常会用到count(1)、count(*)或者count(字段)&#xff0c;而这三种哪个方式的count效率最高呢&#xff1f;先来说结论&#xff1a; count(1) count(*) > count(字段) 为什么会得到如上的结论&#xff0c;下面来…

1672_MIT 6.828 xv6中如何通过构建环境让系统中增加一个可执行调用文件

全部学习汇总&#xff1a; GreyZhang/g_unix: some basic learning about unix operating system. (github.com) 前面已经分析了如何实现一个系统调用&#xff0c;这个过程的梳理也已经整理成了一份学习笔记。这一次看一下&#xff0c;如何让OS的系统中增加这样的一个可执行的文…

Arduino2.0.4的安装以及上传错误:exit status2

一、安装并下载Arduino 可以进入到下面这个网站中下载会比较快。 Arduino IDE下载&#xff08;9月15日更新到2.0&#xff09;-Arduino爱好者 - Powered by Discuz! Arduino IDE下载&#xff08;9月15日更新到2.0&#xff09;-Arduino爱好者 - Powered by Discuz!Arduino IDE下…

【基于冗余缩减变换:Pan-Sharpening】

Pan-Sharpening Based on Transformer With Redundancy Reduction &#xff08;基于冗余缩减变换的全色锐化算法&#xff09; 基于深度神经网络&#xff08;DNN&#xff09;的泛锐化方法已经产生了最先进的结果。然而&#xff0c;在全色&#xff08;PAN&#xff09;图像和低空…

Python-Python基本用法(全:含基本语法、用户交互、流程控制、数据类型、函数、面向对象、读写文件、异常、断言等)

1 环境准备 编辑器&#xff1a;Welcome to Python.org 解释器&#xff1a;pycharm&#xff1a;Thank you for downloading PyCharm! (jetbrains.com) 2 Quick start 创建项目 new project create demo print(Dad!!)3 基本语法 3.1 print 直接打印 print(Dad!!)拼接打印…

AD20添加元件3D库

Altium Designer是画PCB常用的工具之一,为了PCB的美观性,我们可以采用3D的方式查看已经画好的PCB板。但在这之前需要准备好每个元器件的3D模型。 1、下载3D格式模型 http://www.3dcontentcentral.cn 当然要先注册账户。 在搜索栏输入你想要找的器件。 模型格式STEP AP214…

vue-cli 初始化工程

个人记录下vue-cli创建项目的步骤 卸载老版本的vue-cli (这不是必要的) npm uninstall vue-cli -g 如果本地使用 yarn的话,还需执行 yarn global remove vue-cli 安装全新的vue-cli npm install -g vue/cli 安装指定版本的vue-cli npm install -g vue/…

linux 安装git并拉取代码教程

#一步一步执行以下命令sudo apt install git #安装gitgit --version #查看安装版本号git config user.name jtr #设置用户名git config user.email jiangtrcloudskysec.com #设置邮箱ssh-keygen -t rsa -C "jiangtrcloudskysec.com" #生成秘钥&#xff0c;一直往下按…

自动化测试框架:DrissionPage(1)——安装与设置

发现了一款基于Python的网页自动化工具&#xff1a;DrissionPage。这款工具既能控制浏览器&#xff0c;也能收发数据包&#xff0c;甚至能把两者合而为一&#xff0c;简单来说&#xff1a;集合了WEB浏览器自动化的便利性和 requests 的高效率优点。 一、DrissionPage框架产生背…

【C++进阶】01:概述

概述 OVERVIEW概述C11新特性&#xff1a;C14新特性&#xff1a;C17新特性&#xff1a;C20新特性&#xff1a;C程序编译过程C内存模型CSTL1.Queue&Stack2.String3.MapC语言C语言面向过程编程✅✅面向对象编程&#xff08;类和对象&#xff09;❌✅泛型编程、元编程&#xff…