使用alloca-c2hs

时间:2017-11-23 16:03:22

标签: haskell ffi alloca c2hs

从c2hs文档中考虑一下:

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

在Haskell中生成

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

绑定以下C函数:

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

问题:在这里,我很困惑alloca-对左侧的影响,即`Bool'

现在我知道,在实践中,正在发生的事情是alloca以某种方式生成Ptr BoolpeekBool可以转换为输出参数。但令我非常困惑的是alloca如何做到这一点,因为它的类型签名为alloca :: Storable a => (Ptr a -> IO b) -> IO b。更具体地说:

问题1。当有人在Haskell中调用notebookQueryTabLabelPacking时,c2hs为alloca的第一个参数(Ptr a -> IO b)提供了哪些参数?

问题2。在这种情况下,alloca的第一个参数(Ptr a -> IO b)的具体类型签名是什么?是(Ptr CBool -> IO CBool)吗?

1 个答案:

答案 0 :(得分:0)

c2hs将调用alloca 3次,为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操作中。

请注意,lambdas都会指向其分配的存储空间,并返回IO (Bool, Bool, PackType)