I want to use the cFromEnum
function, but this resides in the C2HS
module, which I'm told is unnecessary and shouldn't be unpacked / installed ( c2hs not getting installed / registered correctly ). What's the modern way to convert an enum? For concreteness, here's my code.
{# enum BNType {underscoreToCase} deriving (Show, Eq) #}
{# pointer *NodeVector newtype #}
{# fun get_nodes_by_type { cFromEnum `BNType' } -> `NodeVector' id #}
(get_nodes_by_type
will eventually take an argument; I'm just trying to get something working for now).
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).