联盟和类型**与Haskell FFI?

我需要知道如何解析工会和键入**(例如int **)与FFI? 我知道我需要一个可存储结构的实例,我可以将它用于工会吗?

这样的联盟:

typedef union {
     int i;
     char c;
} my_union;

这通常会在Haskell中表示为:

data MyUnion = I CInt | C CChar

我的问题是你将如何marshall(为myUnion定义一个Storable实例)到my_union中? 我的理解是my_union会在内存中占用sizeof(int)个字节,即它的最大成员的大小。 所以为了保存这个,我们会写下如下的内容:

instance Storable myUnion where
     size _ = #{size my_union} -- <-- hsc2hs shortcut
     alignment _ = alignment undefined::CInt -- <-- What should this really be?
     peek ptr = do -- <-- How are you supposed to know which element to extract?
     poke ptr (I i) =  poke ptr i -- <-- Or should this be #{poke my_union, i} ptr i ?
     poke ptr (C c) = poke ptr c

另外,如何用FFI表示一个int** ? 当我有一个像int foo(int i1, int* i2);这样的函数int foo(int i1, int* i2); 签名应该是: foo -> CInt -> Ptr CInt -> CInt

但如果有int foo(int i1, int** i2);


C联盟没有标记联盟,请参阅关于此的维基百科。 在haskell中,MyUnion将占用比单个原始(未装箱)的64位int更多的内存。 在GHC中,它将是一个特殊的指针,指向一个thunk或一个值:当一个懒惰的MyUnion尚未被评估时,该值就是当它被评估并且指向的内存大小可以变化时的值(不同于联合在C)。 “特殊”指针将使用64位指针的通常为零的低位来指示它是否已知为C或I值,以将标记与指针组合在一起。

Haskell中的懒惰声明可以使用

data MyUnion1 = I !Int | C !Char
data MyUnion2 = I {-# UNPACK #-} !Int | C {-# UNPACK #-} !Char

凡“!” 表示该值永远不会被存储为未评估的thunk。 UNPACK编译器编译指示注释要求GHC将原始的取消装箱值与标记一起存储,而不是存储指向Int或Char的指针。 所以MyUnion2可能会占用更少的内存,并且会严格而不是懒惰。

另外,我应该强调来自C的“char”是一个有符号的字节,而Haskell中的“Char”是一个完整的unicode代码点(值为0到1114111)。 要在Haskell中存储一个C“字符,你可以使用一个CChar。

你有C中使用的工会,需要序列化和desearialize他们? 你已经有一个C使用的二进制格式? 如果你需要发明一种二进制格式,那么你需要设计一个标签来让Haskell开心。 您的C示例无法判断值是使用int还是char构造的,而Haskell中的MyUnion可以判断该值是由I还是C构造的。

你写的C类型也是相当危险的,就像我写入单字节“char”并读取多字节“int”一样,“int”中的其余字节可能未定义。


即使是在C语言中,如果你交给某个人,你也不会知道使用哪个成员(除非从上下文清楚)

typedef union {
     int i;
     char c;
} my_union;

C解决方案是添加一个带有该类型的额外成员。

typedef struct {
     int type;
     union {
          int i;
          char c;
     } my_union;
} my_tagged_union;

哟可以轻松地将指针指向指针(我使用类似的方式将(void*)&val参数传递给C库)。 在ghci上:

> a <- malloc :: (IO (Ptr Int))
> dir_a <- malloc :: (IO (Ptr (Ptr Int)))
> poke dir_a a
> poke a 5

> b <- peek dir_a
> peek b
5
链接地址: http://www.djcxy.com/p/61173.html

上一篇: Union and Type** with FFI in Haskell?

下一篇: importing c++ data types to haskell with ffi