문제

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).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top