0

Consider from the c2hs documentation that this:

{#fun notebook_query_tab_label_packing as ^
  `(NotebookClass nb, WidgetClass cld)' =>
  {notebook `nb'                ,
  widget   `cld'               ,
  alloca-  `Bool'     peekBool*,
  alloca-  `Bool'     peekBool*,
  alloca-  `PackType' peekEnum*} -> `()'#}

generates in Haskell

notebookQueryTabLabelPacking :: (NotebookClass nb, WidgetClass cld)
          => nb -> cld -> IO (Bool, Bool, PackType)

which binds the following C function:

void gtk_notebook_query_tab_label_packing (GtkNotebook *notebook,
            GtkWidget   *child,
            gboolean    *expand,
            gboolean    *fill,
            GtkPackType *pack_type);

Problem: Here I'm confused what the effect of alloca- has on the left side of, i.e., `Bool'.

Now I know that, in practice, what is happening is that alloca is somehow generating a Ptr Bool that peekBool can convert into an output argument. But what I'm terribly confused about is how alloca is doing this, given its type signature alloca :: Storable a => (Ptr a -> IO b) -> IO b. More specifically:

Question 1. When someone calls notebookQueryTabLabelPacking in Haskell, what does c2hs provide as argument for alloca's first parameter (Ptr a -> IO b)?

Question 2. In this case, what is the concrete type signature for alloca's first paramater (Ptr a -> IO b)? Is it (Ptr CBool -> IO CBool)?

George
  • 6,927
  • 4
  • 34
  • 67

1 Answers1

0

c2hs will call alloca 3 times to allocate space for the 3 reference arguments. Each call will be provided a lambda that binds the pointer to a name, and returns an IO action that either allocates the space for the next reference argument, or, when all space has been allocated, calls the underlying function, reads the values of the reference arguments, and packages them into a tuple. Something like:

notebookQueryTabLabelPacking nb cld =
  alloca $ \a3 -> do
    alloca $ \a4 -> do
      alloca $ \a5 -> do
        gtk_notebookQueryTabLabelPacking nb cld a3 a4 a5
        a3' <- peekRep a3
        a4' <- peekRep a4
        a5' <- peekRep a5
        return (a3', a4', a5')

Each alloca is nested in the IO action of the previous one.

Note that the lambdas all take a pointer to their allocated storage, and return an IO (Bool, Bool, PackType).

pat
  • 12,587
  • 1
  • 23
  • 52