【C++】ImGui:VSCode下的无依赖轻量GUI开发
本教程将手把手带您用纯原生方式构建ImGui应用,无需CMake/第三方库。您将全程明了自己每个操作的意义,特别适合首次接触GUI开发的新手。
环境配置
安装VSCode
- 作用:轻量级代码编辑器,提供智能提示
- 操作:
- 官网下载安装包 → 默认选项安装
- 安装后打开,按下
Ctrl+Shift+X
安装"C/C++ Extension Pack"
配置MinGW
- 作用:提供Windows下的GCC编译环境
- 操作:
- 访问WinLibs下载MinGW-W64 GCC 14.2.0 + LLVM/Clang/LLD/LLDB 19.1.7的Release包
- 解压到
C:\mingw64
(路径不可含中文) - 右键开始菜单 → 系统 → 高级系统设置 → 环境变量 → 在Path中添加
C:\mingw64\bin
验证成功:
打开CMD输入g++ -v
应显示类似gcc version 14.2.0
的版本信息
项目结构解析
创建标准目录
MyProject/
├─.vscode/ # VSCode专属配置
│ ├─tasks.json # 编译指令配置
│ └─settings.json # 头文件路径配置
├─libs/
│ └─imgui/ # ImGui核心库文件
└─src/├─main.cpp # 窗口初始化代码(无需修改)└─Application.hpp # 你的UI主战场
关键说明:
.vscode
:存放编辑器配置,避免每次手动设置libs/imgui
:集中管理第三方库,便于后续升级
获取ImGui源码
精准获取必要文件
- 访问Imgui的GitHub仓库
- 下载ZIP包后解压,按以下清单复制文件:
- 核心组件(来自根目录):
imgui.cpp
,imgui.h
,imgui_*.cpp/h
imstb_*.h
系列文件
- Windows后端(来自backends/):
imgui_impl_win32.h/cpp
imgui_impl_dx11.h/cpp
- 核心组件(来自根目录):
为何需要后端文件:
ImGui本身是平台无关的GUI库,需要特定平台的实现才能显示窗口。这里选择DirectX11作为渲染后端。
配置文件详解
tasks.json(编译指令)
{ "version": "2.0.0", // JSON 配置文件的版本号 "tasks": [ // 定义一个任务列表 { "label": "Build main.exe", // 任务名称,方便识别 "type": "shell", // 任务类型,表示这是一个 shell 命令 "command": "g++", // 使用的编译器命令,这里是 g++ "args": [ // 传递给编译器的参数列表 "-I", // 指定头文件搜索路径 "${workspaceFolder}/libs/imgui", // imgui 库的头文件路径 "-I", // 再次指定头文件搜索路径 "${workspaceFolder}/include", // 项目自己的头文件路径 "src/main.cpp", // 要编译的主源文件 "${workspaceFolder}/libs/imgui/*.cpp", // imgui 库的所有实现文件 "-o", // 用于指定输出文件 "${workspaceFolder}/${workspaceFolderBasename}.exe", // 输出的可执行文件路径 "-static", // 静态链接,用于不依赖 DLL "-L/mingw64/lib", // 指定库文件搜索路径 "-ld3d11", // 链接 Direct3D 11 库 "-ldxgi", // 链接 DXGI 库 "-luser32", // 链接 Windows 用户界面库 "-lgdi32", // 链接 GDI 图形设备接口库 "-lole32", // 链接 OLE 库 "-ldwmapi", // 链接 DWM API 库 "-ld3dcompiler", // 链接 D3D 编译器库 "'-Wl,-subsystem,windows'" // 容器选项:指定生成 Windows 应用程序 ], "group": { // 任务分组信息 "kind": "build", // 组的类型为构建 "isDefault": true // 设定为默认构建任务 } } ]
}
settings.json(智能提示配置)
{ "C_Cpp.default.includePath": [ // C/C++ 扩展的默认头文件搜索路径 "${workspaceFolder}/include", // 项目中包含头文件的路径 "${workspaceFolder}/libs/imgui" // ImGui 库的头文件路径 ], "C_Cpp.default.Definition": [ // C/C++ 扩展的默认宏定义路径 "${workspaceFolder}/include" // 需要使用宏定义的头文件路径 ], "C_Cpp.errorSquiggles": "disabled", // 禁用错误波浪线提示 "C_Cpp.intelliSenseEngine": "default", // 使用默认的智能感知引擎 "C_Cpp.default.compileCommands": "${workspaceFolder}/build/compile_commands.json", // 指定编译命令 JSON 文件的路径(用于基于 CMake 或其他构建系统时提供编译信息) "files.associations": { // 文件类型关联设置 "*.cpp": "cpp", // 将所有 .cpp 文件识别为 C++ 文件 "*.h": "cpp", // 将所有 .h 文件识别为 C++ 文件(兼容 C++ 头文件) "vector": "cpp" // 将名为 vector 的文件/模块识别为 C++ 类型(通常是 STL 的一部分) }
}
编写代码
main.cpp(固定结构,无需修改)
#include "imgui.h"
#include "imgui_impl_win32.h"
#include "imgui_impl_dx11.h"
#include <d3d11.h>
#include <tchar.h>
#include "Application.hpp"// 数据
static ID3D11Device *g_pd3dDevice = nullptr;
static ID3D11DeviceContext *g_pd3dDeviceContext = nullptr;
static IDXGISwapChain *g_pSwapChain = nullptr;
static bool g_SwapChainOccluded = false;
static UINT g_ResizeWidth = 0, g_ResizeHeight = 0;
static ID3D11RenderTargetView *g_mainRenderTargetView = nullptr;// 辅助函数的前向声明
bool CreateDeviceD3D(HWND hWnd);
void CleanupDeviceD3D();
void CreateRenderTarget();
void CleanupRenderTarget();
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);// 主代码
int main(int, char **)
{// 创建应用程序窗口// ImGui_ImplWin32_EnableDpiAwareness();WNDCLASSEXW wc = {sizeof(wc), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(nullptr), nullptr, nullptr, nullptr, nullptr, L"ImGui Example", nullptr};::RegisterClassExW(&wc);HWND hwnd = ::CreateWindowW(wc.lpszClassName, L"Dear ImGui DirectX11 示例", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, nullptr, nullptr, wc.hInstance, nullptr);// 初始化 Direct3Dif (!CreateDeviceD3D(hwnd)){CleanupDeviceD3D();::UnregisterClassW(wc.lpszClassName, wc.hInstance);return 1;}// 显示窗口::ShowWindow(hwnd, SW_SHOWDEFAULT);::UpdateWindow(hwnd);// 设置 Dear ImGui 上下文IMGUI_CHECKVERSION();ImGui::CreateContext();ImGuiIO &io = ImGui::GetIO();(void)io;io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // 启用键盘控制io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // 启用游戏手柄控制// 设置 Dear ImGui 样式ImGui::StyleColorsDark();// ImGui::StyleColorsLight();// 设置平台/渲染器后端ImGui_ImplWin32_Init(hwnd);ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext);// 加载字体// - 如果没有加载字体,Dear ImGui 将使用默认字体。您还可以加载多个字体并使用 ImGui::PushFont()/PopFont() 来选择它们。// - AddFontFromFileTTF() 将返回 ImFont*,如果您需要在多个字体中选择,可以存储它。// - 如果文件无法加载,该函数将返回 nullptr。请在您的应用程序中处理这些错误(例如使用断言,或显示错误并退出)。// - 字体将在给定大小(带过采样)下被栅格化并存储到纹理中,当调用 ImFontAtlas::Build()/GetTexDataAsXXXX() 时,ImGui_ImplXXXX_NewFrame 将在下面调用它。// - 在 imconfig 文件中使用 '#define IMGUI_ENABLE_FREETYPE' 以使用 Freetype 进行更高质量的字体渲染。// - 阅读 'docs/FONTS.md' 获取更多说明和细节。// - 请记住,在 C/C++ 中,如果您想在字符串字面量中包含反斜杠 \,需要写双反斜杠 \\!// io.Fonts->AddFontDefault();// io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f);// io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);// io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);// io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);// ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());// IM_ASSERT(font != nullptr);// 我们的状态bool show_demo_window = true;bool show_another_window = false;ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);// 主循环bool done = false;while (!done){// 轮询并处理消息(输入、窗口调整大小等)// 请参阅下面的 WndProc() 函数,了解我们如何将事件分派到 Win32 后端。MSG msg;while (::PeekMessage(&msg, nullptr, 0U, 0U, PM_REMOVE)){::TranslateMessage(&msg);::DispatchMessage(&msg);if (msg.message == WM_QUIT)done = true;}if (done)break;// 处理窗口最小化或屏幕锁定的情况if (g_SwapChainOccluded && g_pSwapChain->Present(0, DXGI_PRESENT_TEST) == DXGI_STATUS_OCCLUDED){::Sleep(10);continue;}g_SwapChainOccluded = false;// 处理窗口大小调整(我们不在 WM_SIZE 处理程序中直接调整大小)if (g_ResizeWidth != 0 && g_ResizeHeight != 0){CleanupRenderTarget();g_pSwapChain->ResizeBuffers(0, g_ResizeWidth, g_ResizeHeight, DXGI_FORMAT_UNKNOWN, 0);g_ResizeWidth = g_ResizeHeight = 0;CreateRenderTarget();}// 开始 Dear ImGui 帧ImGui_ImplDX11_NewFrame();ImGui_ImplWin32_NewFrame();ImGui::NewFrame();app::RenderUI();// 渲染ImGui::Render();const float clear_color_with_alpha[4] = {clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w};g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, nullptr);g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha);ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());// 呈现HRESULT hr = g_pSwapChain->Present(1, 0); // 使用垂直同步呈现// HRESULT hr = g_pSwapChain->Present(0, 0); // 不使用垂直同步呈现g_SwapChainOccluded = (hr == DXGI_STATUS_OCCLUDED);}// 清理ImGui_ImplDX11_Shutdown();ImGui_ImplWin32_Shutdown();ImGui::DestroyContext();CleanupDeviceD3D();::DestroyWindow(hwnd);::UnregisterClassW(wc.lpszClassName, wc.hInstance);return 0;
}// 辅助函数bool CreateDeviceD3D(HWND hWnd)
{// 设置交换链DXGI_SWAP_CHAIN_DESC sd;ZeroMemory(&sd, sizeof(sd));sd.BufferCount = 2;sd.BufferDesc.Width = 0;sd.BufferDesc.Height = 0;sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;sd.BufferDesc.RefreshRate.Numerator = 60;sd.BufferDesc.RefreshRate.Denominator = 1;sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;sd.OutputWindow = hWnd;sd.SampleDesc.Count = 1;sd.SampleDesc.Quality = 0;sd.Windowed = TRUE;sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;UINT createDeviceFlags = 0;// createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;D3D_FEATURE_LEVEL featureLevel;const D3D_FEATURE_LEVEL featureLevelArray[2] = {D3D_FEATURE_LEVEL_11_0,D3D_FEATURE_LEVEL_10_0,};HRESULT res = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext);if (res == DXGI_ERROR_UNSUPPORTED) // 如果硬件不可用,尝试高性能 WARP 软件驱动res = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_WARP, nullptr, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext);if (res != S_OK)return false;CreateRenderTarget();return true;
}void CleanupDeviceD3D()
{CleanupRenderTarget();if (g_pSwapChain){g_pSwapChain->Release();g_pSwapChain = nullptr;}if (g_pd3dDeviceContext){g_pd3dDeviceContext->Release();g_pd3dDeviceContext = nullptr;}if (g_pd3dDevice){g_pd3dDevice->Release();g_pd3dDevice = nullptr;}
}void CreateRenderTarget()
{ID3D11Texture2D *pBackBuffer;g_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));g_pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &g_mainRenderTargetView);pBackBuffer->Release();
}void CleanupRenderTarget()
{if (g_mainRenderTargetView){g_mainRenderTargetView->Release();g_mainRenderTargetView = nullptr;}
}// 从 imgui_impl_win32.cpp 前向声明消息处理程序
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);// Win32 消息处理程序
// 您可以读取 io.WantCaptureMouse、io.WantCaptureKeyboard 标志来判断 Dear ImGui 是否想使用您的输入。
// - 当 io.WantCaptureMouse 为 true 时,不要将鼠标输入数据分派到您的主应用程序,或者清除/覆盖您的鼠标数据副本。
// - 当 io.WantCaptureKeyboard 为 true 时,不要将键盘输入数据分派到您的主应用程序,或者清除/覆盖您的键盘数据副本。
// 通常,您可以始终将所有输入传递给 Dear ImGui,并根据这两个标志从您的应用程序中隐藏它们。
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))return true;switch (msg){case WM_SIZE:if (wParam == SIZE_MINIMIZED)return 0;g_ResizeWidth = (UINT)LOWORD(lParam); // 队列调整大小g_ResizeHeight = (UINT)HIWORD(lParam);return 0;case WM_SYSCOMMAND:if ((wParam & 0xfff0) == SC_KEYMENU) // 禁用 ALT 应用程序菜单return 0;break;case WM_DESTROY:::PostQuitMessage(0);return 0;}return ::DefWindowProcW(hWnd, msg, wParam, lParam);
}
- 作用:创建窗口、初始化DirectX、处理消息循环
- 你的关注点:无需理解细节,这是框架的"发动机"
Application.hpp(你的创作空间)
// Application.hpp - 在此自由设计界面
#pragma once
#include <imgui.h>
namespace app
{void RenderUI(){ImGui::Begin("My First GUI");// 示例:创建一个红色按钮ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 0, 0, 1));if (ImGui::Button("Click for a Surprise")){// 在此添加点击事件}ImGui::PopStyleColor();ImGui::End();}
}
开发技巧:
- 所有UI代码写在
RenderUI()
函数内 - 使用
ImGui::
开头的函数创建控件 - 按
Ctrl+Space
触发代码提示
构建与调试
一键编译
- 按下
Ctrl+Shift+B
启动编译(编译生成的二进制文件名为项目文件夹名) - 观察底部终端输出:
- 出现
Finished
表示成功 - 错误信息通常指向缺失文件或语法错误
- 出现
运行程序
- 方式一:VSCode终端输入
./app.exe
- 方式二:直接双击生成的
app.exe
预期效果:
显示1280x800窗口,其中包含你设计的UI元素
进阶指引
修改窗口属性
在main.cpp
中搜索以下常量修改:
// 原值
CreateWindow(..., "标题", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, ...)// 修改示例
CreateWindow(..., "新标题", WS_POPUP, 0, 0, 1920, 1080, ...)
学习资源推荐
- ImGui官方Demo源码 - 包含所有控件用法
- ImGui样式编辑器 - 定制界面外观
相关文章:
【C++】ImGui:VSCode下的无依赖轻量GUI开发
本教程将手把手带您用纯原生方式构建ImGui应用,无需CMake/第三方库。您将全程明了自己每个操作的意义,特别适合首次接触GUI开发的新手。 环境配置 安装VSCode 作用:轻量级代码编辑器,提供智能提示操作: 官网下载安装…...
BUU44 [BJDCTF2020]ZJCTF,不过如此1 [php://filter][正则表达式get输入数据][捕获组反向引用][php中单双引号]
题目: 我仿佛见到了一位故人。。。也难怪,题目就是ZJCTF 按要求提交/?textdata://,I have a dream&filenext.php后: ......不太行,好像得用filephp://filter/convert.base64-encode/resourcenext.php 耶?那 f…...
Jetpack Compose — 入门实践
一、项目中使用 Jetpack Compose 从此节开始,为方便起见,如无特殊说明,Compose 均指代 Jetpack Compose。 开发工具: Android Studio 1.1 创建支持 Compose 新应用 新版 Android Studio 默认创建新项目即为 Compose 项目。 注意:在 Language 下拉菜单中,Kotlin 是唯一可…...
通过着装人体剪影预测关键点,以获取人体的二维尺寸数据。复现过程包括获取或生成3D人体数据集、生成轮廓图像、训练模型等步骤
根据文献《1_Clothes Size Prediction from Dressed-Human Silhouettes》复现方法,主要通过着装人体剪影预测关键点,以获取人体的二维尺寸数据。复现过程包括获取或生成3D人体数据集、生成轮廓图像、训练模型等步骤。 以下是进行复现的大致步骤…...
力扣HOT100之哈希:49. 字母异位词分组
这道题自己先想了一遍,定义了一个比较字符串的函数,用二重循环和一个数组来实现字符串的比较,若两个字符串是异位词,那么就返回true,否则返回false,在主函数中,同样用一个二重循环来遍历向量中的…...
基于单片机的智慧音乐播放系统研究
标题:基于单片机的智慧音乐播放系统研究 内容:1.摘要 随着科技的飞速发展,人们对音乐播放系统的智能化和个性化需求日益增长。本研究的目的是设计并实现一个基于单片机的智慧音乐播放系统。采用单片机作为核心控制单元,结合音频解码模块、存储模块和人机…...
pytest框架 核心知识的系统复习
1. pytest 介绍 是什么:Python 最流行的单元测试框架之一,支持复杂的功能测试和插件扩展。 优点: 语法简洁(用 assert 替代 self.assertEqual)。 自动发现测试用例。 丰富的插件生态(如失败重试、并发执…...
nginx 代理 redis
kubernetes 发布的redis服务端口为 31250 通过命令查询 [miniecs-88500735 /]$ minikube service redis --url http://192.168.49.2:31250[rootecs-88500735 /]# vi /etc/nginx/nginx.conf配置nginx.conf stream {upstream redis {server 192.168.49.2:31250;}server {liste…...
什么是:分布式贝叶斯推断
什么是:分布式贝叶斯推断 分布式贝叶斯推断(Distributed Bayesian Inference)是一种在分布式计算环境下进行贝叶斯统计推断的方法,旨在利用多节点或多设备的并行计算能力,高效处理大规模数据或复杂模型。其核心思想是将数据、模型或计算过程分解到多个节点上,通过协作完…...
C# 命名空间(Namespace)详解
在C#中,命名空间(Namespace)是一种封装和组织代码的方式,它允许将相关的类、接口、结构体和枚举等类型组织在一起,以避免命名冲突,并提供了一种逻辑上的分组方式。命名空间的使用有助于提高代码的可读性、可…...
ASP.NET Core JWT认证与授权
1.JWT结构 JSON Web Token(JWT)是一种用于在网络应用之间安全传输声明的开放标准(RFC 7519)。它通常由三部分组成,以紧凑的字符串形式表示,在身份验证、信息交换等场景中广泛应用。 2.JWT权限认证 2.1添…...
Docker参数,以及仓库搭建
一。Docker的构建参数 注释: 1.对于CMD,如果不想显示,而是使用交互界面:docker run -ti --rm --name test2 busybox:v5 sh 2.对于CMD,一个交互界面只可以使用一个,如果想多次使用CMD,则用ENTR…...
hooks useModule自定义hooks (二次封装AgGridReact ag-table)自定义表头,自定义表头搜索
场景业务: 多次运用AgGridReact的table 列表 思路: 运用自定义hooks进行二次封装: 通用配置例如:传参的参数,传参的url,需要缓存的key这些键值类 定制化配置例如:需要对table 的一些定制化传…...
机试准备第11天
第一题是浮点数加法,目前写过最长的代码。 #include <stdio.h> #include <string> #include <iostream> #include <vector> using namespace std; int main() {string str1;string str2;while (getline(cin, str1) && getline(cin…...
正则表达式详解
这里写目录标题 一、基本概念1.基本语法2.修饰符3.方括号4.元字符5.量词 二、结构1.匹配模式2.字符组3.量词4.贪婪匹配和惰性匹配5.多选分支6.匹配模式关键词 三、位置1.位置锚点2.分组与引用1.分组与编号2.不保存子组3.括号嵌套4.命名捕获组5.引用捕获组 3.回溯匹配 四、对象方…...
动态扩缩容引发的JVM堆内存震荡:从原理到实践的GC调优指南
目录 一、典型案例:系统发布后的GC雪崩事件 (一)故障现象 1. 刚刚启动时 GC 次数较多 2. 堆内存锯齿状波动 3. GC日志特征:Allocation Failure (二)问题定位 二、原理深度解析:JVM内存弹…...
本地运行Manus的替代方案:OpenManus的技术解析与实践指南
无需邀请码,三小时构建的开源智能体革命 一、背景:从Manus到OpenManus的技术突围 近期,AI智能体领域因Manus的发布引发热议。这款号称“全球首个通用型AI智能体”的产品,通过整合浏览器操作(Browser Use)…...
红果短剧安卓+IOS双端源码,专业短剧开发公司
给大家拆解一下红果短剧/河马短剧,这种看光解锁视频,可以挣金币的短剧APP。给大家分享一个相似的短剧APP源码,这个系统已接入穿山甲广告、百度广告、快手广告、腾讯广告等,类似红果短剧的玩法,可以看剧赚钱,…...
ubuntu22.04本地部署OpenWebUI
一、简介 Open WebUI 是一个可扩展、功能丰富且用户友好的自托管 AI 平台,旨在完全离线运行。它支持各种 LLM 运行器,如 Ollama 和 OpenAI 兼容的 API,并内置了 RAG 推理引擎,使其成为强大的 AI 部署解决方案。 二、安装 方法 …...
不同开发语言之for循环的用法、区别总结
一、Objective-C (1)标准的c风格 for (int i 0; i < 5; i) {NSLog("i %d", i); } (2)for in循环。 NSArray *array ["apple", "banana", "orange"]; for (NSString *fruit in …...
国产编辑器EverEdit - 宏功能介绍
1 宏 1.1 应用场景 宏是一种重复执行简单工作的利器,可以让用户愉快的从繁琐的工作中解放出来,其本质是对键盘和菜单的操作序列的录制,并不会识别文件的内容,属于无差别无脑执行。 特别是对一些有规律的重复按键动作,…...
【Linux跬步积累】—— 网络基础
🌏博客主页:PH_modest的博客主页 🚩当前专栏:Linux跬步积累 💌其他专栏: 🔴 每日一题 🟡 C跬步积累 🟢 C语言跬步积累 🌈座右铭:广积粮࿰…...
【银河麒麟高级服务器操作系统实例】虚拟机桥接网络问题分析及处理
更多银河麒麟操作系统产品及技术讨论,欢迎加入银河麒麟操作系统官方论坛 https://forum.kylinos.cn 了解更多银河麒麟操作系统全新产品,请点击访问 麒麟软件产品专区:https://product.kylinos.cn 开发者专区:https://developer…...
深入剖析Android Service:原理、生命周期与实战应用
一、引言:开启 Service 探索之旅 在 Android 开发的广袤天地中,Service 堪称一颗璀璨的明星,占据着举足轻重的地位。它宛如一位幕后英雄,默默地在后台辛勤劳作,执行着各种至关重要的任务,却无需与用户进行…...
MLT媒体程序框架03:滤镜——loudness
EBU R.128协议 引用链接 EBU的全称为European Broadcasting Union ,既欧洲广播联盟,为欧洲与北非各广播业者(包含广播电台与电视台)的合作组织,成立于1950年2月12日,有五十多个正式加盟国,总部位于瑞士日内瓦,目前中国…...
FreeRTOS第15篇:FreeRTOS链表实现细节03_List_t与ListItem_t的奥秘
文/指尖动听知识库-星愿 文章为付费内容,商业行为,禁止私自转载及抄袭,违者必究!!! 文章专栏:深入FreeRTOS内核:从原理到实战的嵌入式开发指南 1 FreeRTOS列表的核心数据结构 FreeRTOS的列表实现由两个关键结构体组成:List_t(列表)和ListItem_t(列表项)。它们共同…...
Spring Boot静态资源访问顺序
在 Spring Boot 中,static 和 public 目录都用于存放静态资源(如 HTML、CSS、JavaScript、图片等文件),但它们在使用上有一些细微的区别。以下是它们的详细对比: 1. 默认优先级 Spring Boot 会按照以下优先级加载静态…...
什么是 spring 的循环依赖?
什么是 spring 的循环依赖? 首先,认识一下什么是循环依赖,举个例子:A 对象被 Spring 管理,并且引入的 B 对象,同样的 B 对象也被 Spring 管理,并且也引入的 A 对象。这种相互被引用的情况&#…...
RSA的理解运用与Pycharm组装Cryptodome库
1、RSA的来源 RSA通常指基于RSA算法的密码系统,令我没想到的是,其名字的来源竟然不是某个含有特别意义的单词缩写而成(比如PHP:Hypertext Preprocessor(超文本预处理器)),而是由1977年提出该算法的三个歪果…...
AI数据分析:deepseek生成SQL
在当今数据驱动的时代,数据分析已成为企业和个人决策的重要工具。随着人工智能技术的快速发展,AI 驱动的数据分析工具正在改变我们处理和分析数据的方式。本文将着重介绍如何使用 DeepSeek 进行自动补全SQL 查询语句。 我们都知道,SQL 查询语…...
git的坑
不小心把工作区的代码全删掉了 首先是名字出错,不知为何gitee任意把我的名字更改。 导致无法push验证 git push -u origin "master 显示:fatal: Authentication failed for https://gitee.com/zhang-great/stm32-smart-security-system.git/ 我…...
小程序事件系统 —— 32 事件系统 - 事件分类以及阻止事件冒泡
在微信小程序中,事件分为 冒泡事件 和 非冒泡事件 : 冒泡事件:当一个组件的事件被触发后,该事件会向父节点传递;(如果父节点中也绑定了一个事件,父节点事件也会被触发,也就是说子组…...
PLC数据类型和C#数据类型的数据类型映射表
数据类型映射表 PLC数据类型C#数据类型读取方式补充说明BitboolDBX布尔值BytebyteDBB单字节无符号整数WordushortDBW16位无符号整数DWorduintDBD32位无符号整数Intshort16位有符号整数DIntint32位有符号整数RealfloatDBR单精度浮点数LRealdoubleDBL双精度浮点数Stringstr…...
全球首创!微软发布医疗AI助手,终结手写病历时代
今天凌晨,微软发布了医疗界首个用于临床工作流程的AI助手Microsoft Dragon Copilot。 Dragon Copilot是基于语音文本的混合架构,能够将医生的语音或临床口述内容实时转换为文本。例如,医生可以通过语音输入患者的病历信息、医嘱或诊断结果&a…...
每日一题----------异常处理
总结: NullPointerException:尝试使用一个空引用进行操作时抛出。 ArrayIndexOutOfBoundsException:数组下标越界时抛出。 ClassCastException:类型转换失败时抛出。 ArithmeticException:数学运算错误时抛出&#…...
HTML 属性(详细易懂)
HTML(超文本标记语言)是用于创建网页和其他可在浏览器中查看的内容的基础标记语言。HTML 属性是 HTML 元素的额外信息,它们提供了元素的更多细节,如元素的标识符、样式、行为等。在本文中,将详细介绍 HTML 属性&#x…...
基于火山引擎的DeepSeek-V3 api实现简单的数据查询功能
前言 现在ai比较火,ai可以极大的提高大家的工作效率,所以有空的话要学习下ai的使用 火山引擎大模型 火山引擎大模型广场,聚集了市面上常见的基座大模型,每个模型都有50Wtokens的免费调用量,可以方便大家调用 账号登…...
AI入门1:关键概念
1. 基础概念 AI(Artificial Intelligence,人工智能) 模拟人类智能的机器系统,具备学习、推理、决策等能力。 Machine Learning(机器学习,ML) 让计算机通过数据自动学习规律,…...
WPS工具栏添加Mathtype加载项
问题描述: 分别安装好WPS和MathType之后,WPS工具栏没直接显示MathType工具,或者是前期使用正常,由于WPS更新之后MathType工具消失,如下图 解决办法 将文件“MathType Commands 2016.dotm”和“MathPage.wll”从Matht…...
【MySQL-数据类型】数据类型分类+数值类型+文本、二进制类型+String类型
一、数据类型分类 二、数值类型 1.bit类型 测试环境ubuntu 基本语法: bit[(M)]:位字段类型,M表示每个值的位数,范围从1~64;如果M被忽略,默认为1举例: create table testBit(id i…...
cuda矩阵转置算子(共享内存)
cpu版本 即为按行遍历行列互换 // 主机上的矩阵转置函数,用于验证结果 void cpuTranspose(const float *input, float *output, int n) {for (int row 0; row < n; row){for (int col 0; col < n; col){output[col * n row] input[row * n col];}} }gp…...
GB28181视频监控流媒体平台LiveGBS如何自定义收流端口区间以便减少收流端口数或解决端口冲突问题
LiveGBS GB28181流媒体服务在接收视频的时候默认是使用30000-30249, webrtc流播放端口区间默认是UDP的30250-30500区间。有些网络环境不方便开放这么大的端口区间,下面介绍下如何修改配置这个区间。 从页面上修改这个区间,端口区间尽量设置大…...
在Go语言中,判断变量是否为“空”(零值或未初始化状态)的方法总结
在Go语言中,判断变量是否为“空”(零值或未初始化状态)的方法因数据类型而异。以下是各类型变量的判断方法总结: 1. 基本类型 整数(int) 判断是否等于零值 0。 var i int if i == 0 { // 空 } 字符串(string) 判断是否等于空字符串 ""。 var s string if s =…...
VUE3开发-9、axios前后端跨域问题解决方案
VUE前端解决跨域问题 前端页面需要改写 如果无效,记得重启服务器 后端c#解决跨域问题 前端js取值,后端c#跨域_c# js跨域-CSDN博客...
利用 requestrepo 工具验证 XML外部实体注入漏洞
1. 前言 在数字化浪潮席卷的当下,网络安全的重要性愈发凸显。应用程序在便捷生活与工作的同时,也可能暗藏安全风险。XXE(XML外部实体)漏洞作为其中的典型代表,攻击者一旦利用它,便能窃取敏感信息、掌控服务…...
嵌入式开发之串行数据处理
前题 前面几篇文章写了关于嵌入式软件开发时,关于串行数据处理的一些相关内容,有兴趣的可以看看《嵌入式开发:软件架构、驱动开发与串行数据处理》、《嵌入式软件开发之生产关系模型》和《嵌入式开发之Modbus-RTU协议解析》相关的内容。从业十…...
深入解析 JVM —— 从基础概念到实战调优的全链路学习指南
文章目录 一、为什么要学习 JVM?1. 面试必备与技能提升2. 性能优化与问题诊断3. 编写高质量代码 二、JVM 基础概念与体系结构1. JVM 简介2. JDK、JRE 与 JVM 三、JVM 内存模型1. 线程私有区2. 线程共享区 四、类加载机制与双亲委派1. 类加载过程2. 双亲委派模型3. 动…...
LTC6804、LTC6811、LTC6813的使用
FSEC自制BMS第一步:从零开发使用LTC6804采集电池电压 LTC6811特性 LTC6811 是 LTC6804 的引脚兼容型升级器件,LTC6804官方已经不推荐选用 可测量多达 12 节串联电池 1.2mV 最大总测量误差 可堆叠式架构能支持几百个电池 内置 isoSPI™ 接口 可在 290μ…...
Spring 构造器注入和setter注入的比较
一、比较说明 在 Spring 框架中,构造器注入(Constructor Injection)和 Setter 注入(Setter Injection)是实现依赖注入(DI)的两种主要方式。它们的核心区别在于依赖注入的时机、代码设计理念以及…...
【LangChain】对话历史管理
1 历史记录的剪裁 trimmed_messages from langchain_core.messages import (AIMessage,HumanMessage,SystemMessage,trim_messages, ) from langchain_openai import ChatOpenAImessages [SystemMessage("youre a good assistant, you always respond with a joke."…...