AFAICT, at this point c2hs users are left writing their own marshalling functions. Unfortunately marshallers have to be names, not arbitrary expressions, so you can't use fromIntegral . fromEnum
as a marshaller within a c2hs declaration.
Presently I write marshallers myself and include them in the .c2hs file. Here are some marshallers from one of my more complicated bindings. I find the situation for withObject
particularly galling, but not so much so that I've attempted to fix it myself yet.
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)
Arguably, many of these should be extracted and put into a common library. If it were bundled with the c2hs package, that would be perfect (IMHO the C2HS module was removed a bit prematurely).