Haskell FFI对C语言递归结构体和联合体的支持

4

我正在尝试编写 Haskell FFI 绑定到一些 C 结构体。以下是一个示例:

typedef struct s0{int a; 
                  union{unsigned char b; 
                        struct s0*c; 
                        struct{unsigned char d[1];
                         }; };}*S;

我的问题是如何使用chs(用于c2hs)或hsc(用于hsc2hs)格式编写它的绑定?我查看了c2hs的教程,但要么没有足够的信息,要么就没有以帮助我编写上述定义的chs文件的方式理解它。
我可以使用HSFFIG工具生成Haskell绑定,但它使用自定义访问方法HSFFIG.FieldAccess.FieldAccess来定义绑定。我更喜欢编写使用核心Haskell FFI库而不是第三方库的绑定。
因此,这个问题是关于如何编写递归结构的绑定,该递归结构使用hsc格式或仅使用核心FFI库的chs格式。
实际的定义更加复杂,但一旦我弄清楚如何为c2hs或hsc2hs工具编写上述结构定义,我就可以从那里开始。我知道需要为内部联合和结构定义Storable实例,但我不知道如何为上面的递归定义编写包装器。特别地,如何从外部结构中访问结构/联合体内部?我查看了HSFFIG的定义,但访问方法是由HSFFIG定义的。因此,我无法弄清楚如何将其转换为仅使用核心FFI库的chs定义。
我在StackOverflow上看到的问题似乎是关于较简单定义的。如果有类似的答案,请指教。

你实际上需要对数据做任何处理吗?有可能你可以使用void数据类型来避免处理数据。 - alternative
是的,我确实需要处理这些数据。上述结构体的指针作为参数之一传递给另一个 FFI C 函数,并且该函数返回一个结构体值。 - Sal
听起来你好像不在乎数据。 - alternative
返回的结构体值将在Haskell代码中使用,在检索相关值并使用相关访问器函数后使用。因此,它很重要。FFI性能(以及数据被编组的数量)并不是真正重要的。 - Sal
你想直接读写C数据,还是将其转换为Haskell数据进行编组/解组?编组/解组会复制整个数据结构,但使用起来更容易。 - Heatsink
1个回答

1

在c2hs或hsc2hs中,你无法神奇地创建一个等效的数据结构。然而,只需一点工作,你就可以在c2hs中自己进行编组。

data MyType = Next MyType | MyChar Char | MyString String | MyEnd

然后使用hsc2hs的新类型指针功能声明一个MyType(即s0)的指针。然后,编写一个显式函数,使用hsc2hs的访问器递归遍历您的结构并构建您的Haskell结构。在每个步骤中,您都会测试是否已经到达了空指针,如果是,则返回MyEnd(或者根据数据编码,只需检查联合中表示类型的int是否为负一或其他),否则继续解析您拥有的任何内容,如果该内容是指针,则继续递归。

您也可以使用hsc2hs几乎相同的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接