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)?

4

1 回答 1

0

c2hs 将调用alloca3 次为 3 个引用参数分配空间。每个调用都将提供一个 lambda,它将指针绑定到一个名称,并返回一个IO操作,该操作为下一个引用参数分配空间,或者在分配所有空间后调用底层函数,读取引用的值参数,并将它们打包成一个元组。就像是:

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')

每个alloca都嵌套IO在前一个的动作中。

请注意,lambda 都采用指向其分配存储的指针,并返回一个IO (Bool, Bool, PackType).

于 2017-11-27T19:42:06.903 回答