Summary
BuildMonitor.cs carries an unsafe workaround for a binding bug in Hexa.NET.ImGui, and its own comment says the upstream issue was never actually filed — the link is a placeholder:
// TODO: Remove this workaround once Hexa.NET.ImGui fixes the ImGuiTableColumn struct layout.
// The binding incorrectly uses sbyte/byte for ImGuiTableColumnIdx/ImGuiTableDrawChannelIdx fields
// which should be short/ushort (2 bytes each). This makes the C# struct 8 bytes smaller than native.
// See: https://github.com/HexaEngine/Hexa.NET.ImGui/issues/XXX (report this issue)
(BuildMonitor/BuildMonitor.cs, around line 120.)
The underlying bug
Eight fields are bound at the wrong width. Five are ImGuiTableColumnIdx (ImS16) — DisplayOrder, IndexWithinEnabledSet, PrevEnabledColumn, NextEnabledColumn, SortOrder — and three are ImGuiTableDrawChannelIdx (ImU16) — DrawChannelCurrent, DrawChannelFrozen, DrawChannelUnfrozen. Each should be 2 bytes and is bound as 1, leaving the C# struct 8 bytes smaller than the native one.
Why this is worth tracking
SaveColumnWidth reads column widths out of ImGui's native structs by hand, using GetNativeImGuiTableColumnSize() — sizeof(ImGuiTableColumn) plus a hardcoded ImGuiTableColumnSizeDifference = 8. That is pointer arithmetic against an assumed native layout:
- It is silently wrong if upstream fixes the binding (the
Debug.Assert on csharpSize < 112 only fires in Debug builds, so a Release build would keep applying a now-incorrect +8 offset and read from the wrong address).
- It is silently wrong if Dear ImGui itself changes
ImGuiTableColumn.
- It is the reason the project needs
AllowUnsafeBlocks at all.
Suggested work
- File the issue against HexaEngine/Hexa.NET.ImGui describing the eight mis-bound fields, and replace the
issues/XXX placeholder with the real link.
- Promote the
Debug.Assert to a runtime check that degrades gracefully — falling back to DefaultColumnWidths and logging — rather than reading from a wrong offset in Release.
- Once upstream ships a fix, take the version bump, delete
ImGuiTableColumnSizeDifference and GetNativeImGuiTableColumnSize, and drop AllowUnsafeBlocks if nothing else needs it.
Summary
BuildMonitor.cscarries an unsafe workaround for a binding bug in Hexa.NET.ImGui, and its own comment says the upstream issue was never actually filed — the link is a placeholder:(
BuildMonitor/BuildMonitor.cs, around line 120.)The underlying bug
Eight fields are bound at the wrong width. Five are
ImGuiTableColumnIdx(ImS16) —DisplayOrder,IndexWithinEnabledSet,PrevEnabledColumn,NextEnabledColumn,SortOrder— and three areImGuiTableDrawChannelIdx(ImU16) —DrawChannelCurrent,DrawChannelFrozen,DrawChannelUnfrozen. Each should be 2 bytes and is bound as 1, leaving the C# struct 8 bytes smaller than the native one.Why this is worth tracking
SaveColumnWidthreads column widths out of ImGui's native structs by hand, usingGetNativeImGuiTableColumnSize()—sizeof(ImGuiTableColumn)plus a hardcodedImGuiTableColumnSizeDifference = 8. That is pointer arithmetic against an assumed native layout:Debug.AssertoncsharpSize < 112only fires in Debug builds, so a Release build would keep applying a now-incorrect +8 offset and read from the wrong address).ImGuiTableColumn.AllowUnsafeBlocksat all.Suggested work
issues/XXXplaceholder with the real link.Debug.Assertto a runtime check that degrades gracefully — falling back toDefaultColumnWidthsand logging — rather than reading from a wrong offset in Release.ImGuiTableColumnSizeDifferenceandGetNativeImGuiTableColumnSize, and dropAllowUnsafeBlocksif nothing else needs it.