当前位置: 首页 > article >正文

【C++】ImGui:VSCode下的无依赖轻量GUI开发

本教程将手把手带您用纯原生方式构建ImGui应用,无需CMake/第三方库。您将全程明了自己每个操作的意义,特别适合首次接触GUI开发的新手。

环境配置

安装VSCode

  • 作用:轻量级代码编辑器,提供智能提示
  • 操作
    1. 官网下载安装包 → 默认选项安装
    2. 安装后打开,按下Ctrl+Shift+X安装"C/C++ Extension Pack"

配置MinGW

  • 作用:提供Windows下的GCC编译环境
  • 操作
    1. 访问WinLibs下载MinGW-W64 GCC 14.2.0 + LLVM/Clang/LLD/LLDB 19.1.7的Release包
    2. 解压到C:\mingw64(路径不可含中文)
    3. 右键开始菜单 → 系统 → 高级系统设置 → 环境变量 → 在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源码

精准获取必要文件

  1. 访问Imgui的GitHub仓库
  2. 下载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应用&#xff0c;无需CMake/第三方库。您将全程明了自己每个操作的意义&#xff0c;特别适合首次接触GUI开发的新手。 环境配置 安装VSCode 作用&#xff1a;轻量级代码编辑器&#xff0c;提供智能提示操作&#xff1a; 官网下载安装…...

新编大学应用英语综合教程2 U校园全套参考答案

全套答案获取&#xff1a; 链接&#xff1a;https://pan.quark.cn/s/389618f53143...

Python数据可视化——Matplotlib的基本绘图:图形、轴、标签

Matplotlib的绘图系统是由多个层次组成的,它的基本结构包括图形(Figure)、坐标轴(Axes)、刻度(Ticks)、标签(Labels)等多个部分。理解这些基本组件,有助于更好地使用Matplotlib绘制和优化图表。在本节中,我们将结合NumPy数组,详细讲解Matplotlib的基本结构,并展示…...

STM32之软件SPI

SPI传输更快&#xff0c;最大可达80MHz&#xff0c;而I2C最大只有3.4MHz。输入输出是分开的&#xff0c;可以同时输出输入。是同步全双工。仅支持一主多从。SS是从机选择线。每个从机一根。SPI无应答机制的设计。 注意&#xff1a;所有设备需要共地&#xff0c;时钟线主机输出&…...

Java 实现 Oracle 的 MONTHS_BETWEEN 函数

介绍 因为系统迁移, 有一些函数要转成 Java 版本, Oracle 的 官方介绍 - MONTHS_BETWEEN MONTHS_BETWEEN returns number of months between dates date1 and date2. The month and the last day of the month are defined by the parameter NLS_CALENDAR. If date1 is late…...

【从零开始学习计算机科学】数字逻辑(五) Verilog HDL语言

【从零开始学习计算机科学】数字逻辑(五) Verilog HDL语言 Verilog HDL语言8位全加器8位计数器2位比较器三态驱动器Verilog HDL模块的结构模块声明。端口定义。信号类型。功能描述verilog描述级别verilog关键字verilog标识符编写Verilog HDL源代码的标准数据类型常量变量nets…...

从零开始实现大语言模型(十三):预训练大语言模型GPTModel

1. 前言 使用梯度下降算法通过下一个token预测任务预训练大语言模型GPTModel&#xff0c;前向传播流程每次会输入一个batch的长度均为context_len的训练样本&#xff0c;执行 batch_size context_len \text{batch\_size}\times\text{context\_len} batch_sizecontext_len次下…...

Permute for Mac v3.12.1 文件格式转换器 支持M、Intel芯片

Mac毒搜集到的Permute 提供简单的视频格式转换功能&#xff0c;可以简单的将视频文件转换为你想要的格式。将你想要转换的视频拖到软件窗口内&#xff0c;然后选择你想要转换的格式即可。 应用介绍 Permute是一款Mac上易用的媒体格式转换工具&#xff0c;支持视频、音乐和图像…...

DeepSeek group-limited expert routing和负载均衡

Ref https://github.com/deepseek-ai/DeepSeek-V3/blob/main/inference/model.py GitHub - deepseek-ai/EPLB: Expert Parallelism Load Balancer DeepSeek-V3 Technical Report DeepSeek的路由方法 class Gate(nn.Module):def __init__(self, args: ModelArgs):super().__…...

智慧消防新篇章:4G液位/压力传感器,筑牢安全防线!

火灾无情&#xff0c;防患未“燃”&#xff01;在智慧消防时代&#xff0c;如何实现消防水系统的实时监测、预警&#xff0c;保障人民生命财产安全&#xff1f;山东一二三物联网深耕物联网领域&#xff0c;自主研发4G液位、4G压力智能传感器&#xff0c;为智慧消防水位、水压无…...

C++ primier plus 函数探幽第二部分

系列文章目录 C primer plus 第一节 步入C-CSDN博客 C primer plus 第二节 hello world刨析-CSDN博客 C primer plus 第三节 数据处理-CSDN博客 C primer plus 第四节 复合类型-CSDN博客 C primer plus 第五节 循环-CSDN博客 C primier plus 第七节 函数探幽第一部分-CSDN博客 …...

DBus名词术语命名规范详解:构建清晰、规范的DBus通信

引言 DBus&#xff08;Desktop Bus&#xff09;是一种高效、灵活的进程间通信&#xff08;IPC&#xff09;机制&#xff0c;广泛应用于Linux桌面环境中。为了确保DBus通信的清晰性和规范性&#xff0c;DBus定义了一套严格的命名规范&#xff0c;涵盖了总线、服务名、对象路径、…...

用低代码平台集成人工智能:无需专业开发也能实现智能化

引言&#xff1a;人工智能的普及与企业需求 随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;越来越多的企业开始意识到其在提升运营效率、优化客户体验和推动业务创新方面的巨大潜力。从智能客服到自动化决策支持&#xff0c;从数据分析到个性化推荐&#x…...

Java停车平台高并发抢锁技术方案设计 - 慧停宝开源停车管理平台

Java停车平台高并发抢锁技术方案设计 一、业务场景特征 瞬时流量峰值 早晚高峰时段&#xff08;07:30-09:00, 17:30-19:00&#xff09;请求量激增10倍热门商圈停车场每秒并发请求可达5000 QPS 资源竞争特性 单个车位被多人同时抢占&#xff08;超卖风险&#xff09;用户操作链…...

C++关键字:typename 用于依赖名消歧器(disambiguator)

目录 1. 说明 2. 示例 1. 说明 在模板&#xff08;包括别名模板&#xff09;的声明或定义中&#xff0c;非当前实例的成员且依赖于模板参数的名称不视为类型&#xff0c;除非使用关键字 typename 或除非它已被建立为类型名称&#xff08;例如使用 typedef 声明或用于命名基…...

第六课:数据库集成:MongoDB与Mongoose技术应用

本文详细介绍了如何在Node.js应用程序中集成MongoDB数据库&#xff0c;并使用Mongoose库进行数据操作。我们将涵盖MongoDB在Ubuntu 20系统中的安装、Bash命令的CRUD操作、Mongoose数据建模&#xff08;Schema/Model&#xff09;、关联查询与聚合管道&#xff0c;以及实战案例—…...

TypeError: Cannot set properties of undefined (setting ‘xxx‘)

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》 &#x1f35a; 蓝桥云课签约作者、…...

Gravitino源码分析-SparkConnector 实现原理

Gravitino SparkConnector 实现原理 本文参考了官网介绍&#xff0c;想看官方解析请参考 官网地址 本文仅仅介绍原理 文章目录 Gravitino SparkConnector 实现原理背景知识-Spark Plugin 介绍(1) **插件加载**(2) **DriverPlugin 初始化**(3) **ExecutorPlugin 初始化**(4) *…...

windows下使用msys2编译ffmpeg

三种方法&#xff1a; 1、在msys2中使用gcc编译 2、在msys2中使用visual studio编译&#xff08;有环境变量&#xff09; 3、在msys2中使用visual studio编译&#xff08;无环境变量&#xff09; 我的环境&#xff1a; 1、msys2-x86_64-20250221 2、vs2015 3、ffmpeg-7.1…...

Linux内核自定义协议族开发指南:理解net_device_ops、proto_ops与net_proto_family

在Linux内核中开发自定义协议族需要深入理解网络协议栈的分层模型。net_device_ops、proto_ops和net_proto_family是三个关键结构体,分别作用于不同的层次。本文将详细解析它们的作用、交互关系及实现方法,并提供一个完整的开发框架。 一、核心结构体的作用与层级关系 struct…...

可视化+图解链表

链表&#xff08;Linked list&#xff09;是一种常用的数据结构&#xff0c;它由一系列节点组成&#xff0c;每个节点包含数据域和指针域。指针域存储了下一个节点的地址&#xff0c;从而建立起各节点之间的线性关系。 1、链表节点 1.1 节点构成 链表节点如下图所示&#xff…...

Docker参数,以及仓库搭建

一。Docker的构建参数 注释&#xff1a; 1.对于CMD&#xff0c;如果不想显示&#xff0c;而是使用交互界面&#xff1a;docker run -ti --rm --name test2 busybox:v5 sh 2.对于CMD&#xff0c;一个交互界面只可以使用一个&#xff0c;如果想多次使用CMD&#xff0c;则用ENTR…...

正十七边形尺规作图证明——从高斯的发现到几何实现

正十七边形尺规作图证明——从高斯的发现到几何实现 1. 引言&#xff1a;一个历史性的数学突破 在欧几里得几何中&#xff0c;尺规作图&#xff08;仅使用直尺和圆规&#xff09;是最为基础的几何构造方法。古希腊数学家已知如何构造正三角形、正方形和正五边形&#xff0c;但…...

常见Web应用源码泄露问题

文章目录 前言一、常见的源码泄露漏洞git源码泄露SVN源码泄露DS_Store文件泄漏网站备份压缩文件泄露WEB-INF/web.xml泄露CVS泄露.hg源码泄露Bazaar/bzr泄露.swp文件泄露 前言 在Web应用方面对于安全来说&#xff0c;可能大家对SQL注入、XSS跨站脚本攻击、文件上传等一些漏洞已…...

如何使用 Python+Flask+win32print 实现简易网络打印服务1

Python 实现网络打印机&#xff1a;Flask win32print 在工作场景中&#xff0c;我们可能需要一个简单的网页接口&#xff0c;供他人上传文档并自动打印到指定打印机。 本文将演示如何使用 Python Flask win32print 库来实现这一需求。 代码详见&#xff1a;https://github.…...

使用Modelsim手动仿真

FPGA设计流程 在设计输入之后,设计综合前进行 RTL 级仿真,称为综合前仿真,也称为前仿真或 功能仿真。前仿真也就是纯粹的功能仿真,主旨在于验证电路的功能是否符合设计要求,其特点是不考虑电路门延迟与线延迟。在完成一个设计的代码编写工作之后,可以直接对代码进行仿真,…...

DeepSeek、Grok与ChatGPT:AI三巨头的技术博弈与场景革命

## 引言&#xff1a;AI工具的三国杀时代 2025年的AI江湖&#xff0c;DeepSeek以黑马之姿横扫全球应用榜单&#xff0c;Grok 3凭借马斯克的狂言抢占头条&#xff0c;ChatGPT则稳坐行业王座。这场技术竞赛不仅是参数量的比拼&#xff0c;更是一场关于效率、成本与场景适配的终极…...

windows自动锁屏,并且要输入密码。如何取消?

Windows 电脑自动锁屏并需要输入密码&#xff0c;通常是因为系统的 电源和睡眠设置 或 组策略 设定了自动锁屏。你可以按照以下方法取消自动锁屏或去掉密码要求&#xff1a; 方法 1&#xff1a;修改 Windows 设置 取消锁屏时间 Win I 打开 设置&#xff0c;进入 系统 → 电源和…...

Redis 主从复制、哨兵与集群的关系及工作原理详解

一、核心概念与关系 Redis 的 主从复制、哨兵&#xff08;Sentinel&#xff09; 和 集群&#xff08;Cluster&#xff09; 是逐步演进的高可用与分布式解决方案&#xff0c;三者关系如下&#xff1a; 主从复制&#xff1a;数据冗余与读写分离的基础。 哨兵&#xff1a;在主从…...

XSD 对 XML 数据格式验证 java

xsd文件&#xff0c;文件名bean.xsd&#xff0c;放在当前java文件目录下 <?xml version"1.0" encoding"UTF-8"?> <xs:schema xmlns:xs"http://www.w3.org/2001/XMLSchema"><xs:element name"bean"><xs:comple…...