在Haskell中使用FFI进行联盟和类型**?

has*_*mer 2 haskell ffi discriminated-union

我需要知道如何用FFI解决联盟和类型**(例如int**)?我知道我需要一个可存储的结构实例,我也可以将其用于工会吗?

像这样的联盟:

typedef union {
     int i;
     char c;
} my_union;
Run Code Online (Sandbox Code Playgroud)

这通常在Haskell中表示为:

data MyUnion = I CInt | C CChar
Run Code Online (Sandbox Code Playgroud)

我的问题是你如何编组(定义一个可存储的实例)myUnion进入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
Run Code Online (Sandbox Code Playgroud)

另外,你如何int**用FFI 代表?当我得到像int foo(int i1, int* i2); 签名一样的功能时:foo -> CInt -> Ptr CInt -> CInt

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

tib*_*bbe 6

即使在C中你也不知道使用哪个成员(除非从上下文中清楚)如果你被交给了:

typedef union {
     int i;
     char c;
} my_union;
Run Code Online (Sandbox Code Playgroud)

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

typedef struct {
     int type;
     union {
          int i;
          char c;
     } my_union;
} my_tagged_union;
Run Code Online (Sandbox Code Playgroud)