Hand-written C wrapper around Dear ImGui
with SDL3 + SDL_GPU backends, packaged as ImguiSharp.Redist on NuGet.
Consumed by SdlSharp.ImGui
via P/Invoke on imgui_sharp.
src/ C wrapper sources (imgui_sharp.cpp, .h, backend)
third_party/imgui/ Dear ImGui sources (git submodule, pinned tag)
scripts/ SDL3 fetch helpers (sdl3-versions.json + fetch-sdl3.{sh,ps1})
nuget/ImguiSharp.Redist/ .csproj that packs runtimes/<rid>/native/*
.github/workflows/ CI build matrix + tag-triggered NuGet publish
Requirements: CMake 3.20+, a C++ toolchain, and either:
- an environment where
find_package(SDL3 CONFIG)succeeds (system SDL3), or - the bundled fetch script to download a pinned SDL3 dev package.
git submodule update --init --recursive
# macOS: fetch SDL3 framework from the upstream DMG
./scripts/fetch-sdl3.sh
cmake -S . -B build -DSDL3_ROOT="$SDL3_ROOT" -DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release# Windows: fetch SDL3 VC dev package
./scripts/fetch-sdl3.ps1
cmake -S . -B build -A x64 -DSDL3_ROOT="$env:SDL3_ROOT" -DCMAKE_BUILD_TYPE=Release
cmake --build build --config ReleaseOutput: build/libimgui_sharp.dylib (macOS) or build/Release/imgui_sharp.dll (Windows).
libimgui_sharp links against SDL3 but does not ship it. It expects
libSDL3 to be co-located in the same directory at runtime — that's what
SdlSharp.Redist already provides. On macOS the SDL3 install name is
rewritten to @loader_path/libSDL3.dylib so both libraries share one
SDL3 instance.
<PackageReference Include="SdlSharp" Version="..." />
<PackageReference Include="ImguiSharp.Redist" Version="0.1.0-preview.1" />SdlSharp.ImGui depends transitively via SdlSharp; applications only need
to add ImguiSharp.Redist if they use the ImGui binding directly.
Pushing a v* tag triggers .github/workflows/release.yml which builds
all RIDs, packs the .nupkg, and pushes to nuget.org via trusted publishing
(OIDC). First-time setup requires registering this repository as a trusted
publisher on nuget.org.
win-x64, win-x86, win-arm64, osx-x64, osx-arm64. Linux is deferred
(no upstream-prebuilt SDL3 Linux binaries).
Pinned by the third_party/imgui submodule SHA. See the current tag with
git -C third_party/imgui describe --tags HEAD.
cd third_party/imgui
git fetch --tags
git checkout vX.Y.Z # pick the new release tag
cd ../..
git add third_party/imgui
git commit -m "Bump Dear ImGui to vX.Y.Z"Then push — CI rebuilds all 5 RIDs and the new ImguiSharp.Redist preview
can be cut by pushing a v* release tag.
- Read the upstream changelog in
third_party/imgui/docs/CHANGELOG.txt— skim for renamed/removed public APIs, struct layout changes, and new APIs worth wrapping. - Local build still clean — any rename of a field we read directly
(on
ImGuiIO,ImGuiStyle,ImGuiListClipper,ImGuiPayload,ImGuiMultiSelectIO,ImGuiSelectionRequest,ImGuiTableSortSpecs,ImGuiInputTextCallbackData) shows up as a compile error inimgui_sharp.cpp— fix the shim. - Binary-layout check still passes at runtime.
IGSharp_CheckVersioncallsDebugCheckVersionAndDataLayoutwhich validatesImGuiIO,ImGuiStyle,ImVec2/4,ImDrawVert,ImDrawIdxsizes against what the C# caller expects. If this asserts after a bump, the C# wrapper (SdlSharp.ImGui) needs matching struct-layout updates before releasing. - CI green on all 5 matrix legs.
- New APIs worth wrapping? —
git -C third_party/imgui log vOLD..vNEW -- imgui.hshows changes to the public header. Consider exposing any additions that fit the coverage criteria in the API table above.
IMGUI_VERSION_NUMis baked into the shared library. A library/C#-caller mismatch at runtime asserts inDebugCheckVersionAndDataLayoutrather than silently corrupting — always shipImguiSharp.Redistand the matchingSdlSharp.ImGuibinding together.- Breaking upstream changes warrant an
ImguiSharp.Redistmajor version bump. - The
-dockingtag is a separate upstream branch we don't track. Switching would require additional shims for multi-viewport,ImGuiPlatformIO, and dock-builder APIs.
The wrapper exports ~825 IGSharp_* C functions covering essentially the
entire master-branch public API: the everyday widget surface (windows,
layout, ID/style stacks, all widget families, popups, menus, tables, tabs),
the DrawList API, fonts and font introspection, ListClipper, InputText
callbacks, plots, drag and drop, multi-select, table sort specs, logging,
ini settings serialization, clipboard/IME/allocator override setters,
debug and error-recovery tools, and the ImGuiStorage / ImGuiTextFilter
/ ImGuiTextBuffer helpers. The only public APIs not wrapped are
variadic/V-suffix overloads and docking/multi-viewport (see below). For
a concrete list, see src/imgui_sharp.h.
ImGuiIO and ImGuiStyle are exposed as layout-compatible C structs
(IGSharp_IO, IGSharp_Style) — call IGSharp_GetIO() /
IGSharp_GetStyle() to obtain a pointer and read or write fields
directly. Layout match with upstream is enforced at compile time by
the asserts in src/imgui_sharp_layout_check.cpp.
Coverage is otherwise complete; only two categories are deliberately out of scope.
| Category | Examples | Reason | Addable? |
|---|---|---|---|
Variadic / V-suffix overloads |
TextV, TextColoredV, BulletTextV, SeparatorTextV |
The typed/non-variadic form is enough — C# formats at the call site before calling Text(...) |
No — format at call site |
| Docking / multi-viewport | DockSpace, DockBuilder*, ImGuiDockNode, viewport-as-OS-window, the platform/renderer callback table |
Not on the master branch we track, and our SDL3 + SDL_GPU backends are single-viewport | No (until upstream merges to master) |