我正在为具有相当复杂接口的本机库处理haskell绑定。它有很多结构作为其接口的一部分,我一直在使用hsc2hs
和bindings-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
我应该做的事情,还有一些其他工具可以帮助我以更简洁的方式做我想做的事情?
答案 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时,该列表的大小被低估。