Haskell FFI - C结构数组数据字段

时间:2013-07-29 21:31:56

标签: haskell ffi

我正在为具有相当复杂接口的本机库处理haskell绑定。它有很多结构作为其接口的一部分,我一直在使用hsc2hsbindings-DSL包构建接口,以帮助自动化结构绑定。

我遇到的一个问题是包含多维数组的结构。 bindings-DSL documentation描述了用于绑定到

等结构的宏
struct with_array {
   char v[5];
   struct test *array_pointer;
   struct test proper_array[10];
};

使用像

这样的宏
#starttype struct with_array
#array_field v , CChar
#field array_pointer , Ptr <test>
#array_field proper_array , <test>
#stoptype

但是这个库有许多结构,多维数组作为字段,更像是

struct with_multidimensional_array {
   int whatever;
   struct something big_array[10][25][500];
};

#array_field宏似乎只处理数组的第一个维度。是bindings-DSL只是没有用于处理多维数组的宏吗?

我真的很喜欢用于将(可能是多维的)数组绑定到任意索引的StorableArray的宏。似乎在bindings-DSL提供的宏中可以获得必要的信息 - 这里没有宏。

是否有人向bindings-DSL添加了宏?有人为bindings-DSL添加了一个宏吗?我是否已经过了hsc2hs我应该做的事情,还有一些其他工具可以帮助我以更简洁的方式做我想做的事情?

2 个答案:

答案 0 :(得分:1)

好吧,没有人想出任何其他内容,所以我会在评论中考虑这个想法。我将使用#field宏而不是#array_field宏,并指定一个包装StorableArray以使其正常工作的类型。

由于我正在考虑这一点,我意识到可以使用GHC 7.6+支持的新类型级数完全抽象出包装器。我整理了一个名为storable-static-array的包,它在类型级别上获取维度,并提供一个适当的Storable实例来处理本机数组,甚至是多维数组。

我仍然缺少的一件事是,我希望找到一种方法来编写一个bindings-DSL兼容的宏,它可以自动提取维度并负责正确生成维度。不过,对bindings-DSL中的宏进行了一瞥,确信我自己并不知道自己管理它的能力差不多。

答案 1 :(得分:1)

#array_field宏处理具有任何维度的数组。文档已更新,以明确显示。

Haskell等效记录将是一个列表。当窥视和戳戳时,该列表的元素的长度和顺序将对应于数组,因为它被认为是C中的一维数组。因此,字段int example[2][3]将对应于具有6个元素的列表按example[0][0], example[0][1], example[0][2], example[1][0], example[1][1], example[1][2]排序。戳戳时,如果列表中包含的元素超过6个,则只使用前6个元素。

选择此设计是为了与FFI标准库中的peekArray和pokeArray保持一致。在bindings-DSL版本1.0.17之前,有一个错误导致当数组字段的维度大于1时,该列表的大小被低估。