从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 Bool
,peekBool
可以转换为输出参数。但令我非常困惑的是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)
吗?
答案 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)
。