haskell-game / dear-imgui.hs

Haskell bindings to Dear ImGui, an immediate mode GUI toolkit
BSD 3-Clause "New" or "Revised" License
142 stars 31 forks source link

Example "test" segfaults after start #67

Closed dpwiz closed 3 years ago

dpwiz commented 3 years ago

In 1d6b7cc97be6973d46aac84f74a881549f39d9cc

jpwidera commented 3 years ago

I'm not sure, but maybe this is somehow related to a missing default value.

setNextWindowPos is calling Raw.setNextWindowPos posPtr cond nullPtr and this itself is calling SetNextWindowPos(const ImVec2& pos, ImGuiCond cond = 0, const ImVec2& pivot = ImVec2(0, 0));. There the nullptr is not replaced by the default argument.

I guess, in the Raw.setNextWindowPos:

setNextWindowPos :: (MonadIO m) => Ptr ImVec2 -> ImGuiCond -> Ptr ImVec2 -> m ()
setNextWindowPos posPtr cond pivotPtr = liftIO do
  [C.exp| void { SetNextWindowPos(*$(ImVec2* posPtr), $(ImGuiCond cond), *$(ImVec2* pivotPtr)) } |]

The transformation from nullPtr to $(ImVec2 pivotPtr)) casts the void to a ImVec2 and therefore is creating a non-valid memory position. But I'm not sure how it is working exactly.

jpwidera commented 3 years ago

A quick Maybe fix can solve this problem:

setNextWindowPos :: (MonadIO m) => Ptr ImVec2 -> ImGuiCond -> Maybe (Ptr ImVec2) -> m ()
setNextWindowPos posPtr cond Nothing = liftIO do
  [C.exp| void { SetNextWindowPos(*$(ImVec2* posPtr), $(ImGuiCond cond)) } |]
setNextWindowPos posPtr cond (Just pivotPtr) = liftIO do
  [C.exp| void { SetNextWindowPos(*$(ImVec2* posPtr), $(ImGuiCond cond), *$(ImVec2* pivotPtr)) } |]

And the call from setNextWindowPos becomes:

      Just pivotRef -> do
        pivot <- get pivotRef
        with pivot $ \pivotPtr ->
          Raw.setNextWindowPos posPtr cond (Just pivotPtr)
      Nothing -> do
        Raw.setNextWindowPos posPtr cond Nothing
dpwiz commented 3 years ago

So, default value is not null, but a static pointer :thinking: Good catch!

dpwiz commented 3 years ago

It works now!