访问C2HS编组功能的现代方式是什么?

时间:2012-02-27 20:36:51

标签: haskell ffi c2hs

我想使用cFromEnum函数,但这个函数位于C2HS模块中,我告诉它是不必要的,不应该解压缩/安装({{3 })。转换枚举的现代方法是什么?具体来说,这是我的代码。

{# enum BNType {underscoreToCase} deriving (Show, Eq) #}
{# pointer *NodeVector newtype #}
{# fun get_nodes_by_type { cFromEnum `BNType' } -> `NodeVector' id #}

get_nodes_by_type最终会引发争论;我现在只想尝试一些工作。

1 个答案:

答案 0 :(得分:1)

AFAICT,此时c2hs用户正在编写自己的编组功能。不幸的是,marshallers必须是名字,而不是任意表达式,所以你不能在c2hs声明中使用fromIntegral . fromEnum作为编组。

现在我自己编写marshallers并将它们包含在.c2hs文件中。这里有一些来自我更复杂的绑定的marshallers。我发现withObject的情况特别令人痛苦,但并非如此,以至于我自己试图修复它。

cIntToEnum :: Enum a => CInt -> a
cIntToEnum = toEnum . fromIntegral

cIntFromEnum :: Enum a => a -> CInt
cIntFromEnum = fromIntegral . fromEnum

cIntConv :: (Integral a, Num b) => a -> b
cIntConv = fromIntegral

cFloatConv :: (Real a, Fractional b) => a -> b
cFloatConv = realToFrac

-- |since c2hs doesn't allow "with" as an input marshaller,
-- withObject is a synonym.
withObject :: Storable a => a -> (Ptr a -> IO b) -> IO b
withObject = with

withFloatArray :: (Storable b, RealFloat b, RealFloat a) =>
  [a]
  -> (Ptr b -> IO b1)
  -> IO b1
withFloatArray = withArray . map (cFloatConv)

可以说,其中许多应该被提取并放入一个公共的库中。如果它与c2hs软件包捆绑在一起,那将是完美的(恕我直言,C2HS模块被过早删除了。)