ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Dear ImGui 文本输入接入 std::string:使用 imgui_stdlib 包装 InputText

2026/9/10 14:59:01 拓冰建站 浏览量
Dear ImGui 文本输入接入 std::string:使用 imgui_stdlib 包装 InputText Dear ImGui 文本输入接入 std::string使用 imgui_stdlib 包装 InputText【免费下载链接】imguiDear ImGui: Bloat-free Graphical User interface for C with minimal dependencies项目地址: https://gitcode.com/GitHub_Trending/im/imgui在 Dear ImGui 中做工具界面时一个常见需求是输入框的内容要直接落到std::string变量上而不是固定大小的char缓冲区。核心 APIImGui::InputText()的原生签名是char* buf size_t buf_size长度写死在编译期无法自动扩容仓库为此提供了官方扩展misc/cpp/imgui_stdlib.h基于ImGuiInputTextFlags_CallbackResize机制给出std::string版本的InputText/InputTextMultiline/InputTextWithHint包装。本文说明如何把这对文件接入工程、如何调用以及如何判断它工作正常。前提条件已完成 Dear ImGui 的核心集成仓库根目录的imgui*.cpp/imgui*.h是自包含的不需要特定构建流程直接加入现有工程编译即可见 docs/README.md Usage 一节。平台与图形后端已按 docs/EXAMPLES.md 的方式接好初始化CreateContext()每帧NewFrame()→Render()→ 渲染 draw data退出时DestroyContext()。工程是 C 环境可用标准库string。为什么需要包装器原生签名见 imgui.h 中 Widgets: Input with Keyboard 一节IMGUI_API bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags 0, ImGuiInputTextCallback callback NULL, void* user_data NULL);buf_size固定超出容量的输入无法写入。imgui.h在这里直接提示If you want to use InputText() with std::string or any custom dynamic string type, use the wrapper in misc/cpp/imgui_stdlib.h/.cpp!动态扩容由ImGuiInputTextFlags_CallbackResize承担ImGuiInputTextFlags_CallbackResize 1 22, // Callback on buffer capacity changes request // (beyond buf_size parameter value), allowing the string to grow. Notify when the string wants to // be resized (for string types which hold a cache of their Size). You will be provided a new BufSize // in the callback and NEED to honor it. (see misc/cpp/imgui_stdlib.h for an example of using this)docs/FAQ.md 中 How can I interact with standard C types 一题也给出相同结论核心库出于便携性使用原始类型char*而非std::string要配合std::string时指向misc/cpp/imgui_stdlib.h。接入 imgui_stdlib把 misc/cpp/imgui_stdlib.h 与 misc/cpp/imgui_stdlib.cpp 加进工程二选一常规方式两个文件都加入项目编译时包含.cpp代码中只#include头文件头文件注释中给出的快捷方式直接#include实现文件不改动构建脚本。#include misc/cpp/imgui_stdlib.h #include misc/cpp/imgui_stdlib.cpp // -- If you want to include implementation without messing with your project/build.注意第二个#include只在不想动构建系统时使用如果.cpp已经加入了编译目标只包含头文件即可不要两处同时生效。包装器提供三个重载见 misc/cpp/imgui_stdlib.hnamespace ImGui { IMGUI_API bool InputText(const char* label, std::string* str, ImGuiInputTextFlags flags 0, ImGuiInputTextCallback callback nullptr, void* user_data nullptr); IMGUI_API bool InputTextMultiline(const char* label, std::string* str, const ImVec2 size ImVec2(0, 0), ImGuiInputTextFlags flags 0, ImGuiInputTextCallback callback nullptr, void* user_data nullptr); IMGUI_API bool InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags 0, ImGuiInputTextCallback callback nullptr, void* user_data nullptr); }调用方式imgui_stdlib.h 头部注释给出的最小用法文档示例std::string my_string; ImGui::InputText(my string, my_string);传入std::string的指针函数返回bool。imgui.h 的回调注释说明InputText()在内容被编辑时返回 true也可以用IsItemEdited()判断因此典型写法是static std::string path; if (ImGui::InputText(Path, path)) OnPathEdited(); // 内容发生变化包装器内部的工作流程可以在 misc/cpp/imgui_stdlib.cpp 中直接读到调用时强制合并ImGuiInputTextFlags_CallbackResize并以str-capacity() 1作为buf_size、str-c_str()作为缓冲区ImGui 请求扩容时回调InputTextCallback()str-resize(data-BufTextLen)后把data-Buf重新指向str-c_str()即文档所说的 honor 新容量如果调用者另外传入了自己的callback非 resize 事件会被转发给该回调ChainCallback所以你仍可以在包装器上叠加CallbackCharFilter之类的自定义回调。回调数据结构ImGuiInputTextCallbackData的关键字段见 imgui.h 注释BufTextLen为不含零终止符的字节长度BufSize含零终止符C 下即string.capacity() 1在 Resize 回调期间Buf与你传入的缓冲区是同一个。验证接入是否生效运行时验证在输入框中输入内容std::string对象内的文本随之更新函数返回值在内容编辑时为 true。想直观观察缓冲区行为可以参照imgui_demo.cppResize Callback 一节的展示方式把缓冲区的大小打印出来imgui_demo.cpp 中对ImVectorchar版本使用了ImGui::Text(Data: %p\nSize: %d\nCapacity: %d, ...)std::string对应输出size()/capacity()。机制对照运行示例程序后打开ImGui::ShowDemoWindow()进入Widgets - Text Input - Resize Callback小节imgui_demo.cpp。该小节故意用ImVectorchar手写了一遍完整的 resize 回调与自定义包装函数作为imgui_stdlib的机制演示——注释说明 demo 本体不引入string所以标准库版本没有出现在imgui_demo.cpp里两者指向同一套CallbackResize机制。限制与注意事项不要自己再传ImGuiInputTextFlags_CallbackResize。三个包装函数实现里都有IM_ASSERT((flags ImGuiInputTextFlags_CallbackResize) 0)自己传该标志会在断言开启的构建中直接失败。FAQ 给出的性能提醒docs/FAQ.md 明确指出在 UI 元素量大的应用里大量使用std::string可能带来不理想的堆分配开销现代实现的小字符串优化SSO不可配置、各实现不一致。热路径上的短字符串更推荐字符串字面量、静态缓冲区或引擎自带的字符串助手imgui_stdlib包装适合内容确实需要动态增长的场景。自定义字符串类型的可选分支misc/cpp/imgui_stdlib.h 同时被标注为 an example of how you may wrap your own similar types。如果你的字符串容器不是std::string例如ImVectorchar或引擎内部类型不要改包装器而是照 demo 中Funcs::MyResizeCallbackMyInputTextMultiline的写法imgui_demo.cpp Resize Callback 小节自建包装回调里把容器 resize 到data-BufSize并更新data-Buf即可。包装器仅依赖核心 API不需要额外后端或构建配置imconfig.h中定义了IMGUI_DISABLE时整个扩展被跳过头文件用#ifndef IMGUI_DISABLE包裹。完成后的结果是输入框与std::string变量双向同步容量随输入自动增长不再受编译期buf_size限制若 UI 中字符串密集且分配开销敏感按 FAQ 建议评估是否改回定长缓冲区。【免费下载链接】imguiDear ImGui: Bloat-free Graphical User interface for C with minimal dependencies项目地址: https://gitcode.com/GitHub_Trending/im/imgui创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考