Skip to content

Report the Hexa.NET.ImGui ImGuiTableColumn struct-layout bug upstream and track removing the workaround #258

Description

@matt-edmondson

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

  1. File the issue against HexaEngine/Hexa.NET.ImGui describing the eight mis-bound fields, and replace the issues/XXX placeholder with the real link.
  2. 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.
  3. Once upstream ships a fix, take the version bump, delete ImGuiTableColumnSizeDifference and GetNativeImGuiTableColumnSize, and drop AllowUnsafeBlocks if nothing else needs it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions