【问题标题】:Using alloca- with c2hs将 alloca- 与 c2hs 一起使用
【发布时间】:2017-11-23 16:03:21
【问题描述】:

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

【问题讨论】:

    标签: haskell ffi alloca c2hs


    【解决方案1】:

    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 操作中。

    请注意,所有 lambda 表达式都采用指向其分配存储的指针,并返回 IO (Bool, Bool, PackType)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多