Qual è il modo moderno per accedere alle funzioni di marshalling C2HS?
Domanda
Voglio usare il cFromEnum
funzione, ma questo risiede in C2HS
Modulo, che mi viene detto che non è necessario e non dovrebbe essere disimballato / installato ( C2H non viene installato / registrato correttamente ). Qual è il modo moderno per convertire un enum? Per la concretezza, ecco il mio codice.
{# enum BNType {underscoreToCase} deriving (Show, Eq) #}
{# pointer *NodeVector newtype #}
{# fun get_nodes_by_type { cFromEnum `BNType' } -> `NodeVector' id #}
(get_nodes_by_type
alla fine prenderà una discussione; Sto solo cercando di far funzionare qualcosa per ora).
Soluzione
AFAICT, a questo punto gli utenti C2HS vengono lasciati a scrivere le proprie funzioni di marshalling. Sfortunatamente i marshaller devono essere nomi, non espressioni arbitrarie, quindi non puoi usare fromIntegral . fromEnum
come un marshaller all'interno di una dichiarazione C2HS.
Attualmente scrivo i marshaller e li includo nel file .c2hs. Ecco alcuni marshaller di uno dei miei attacchi più complicati. Trovo la situazione per withObject
Particolarmente malvagio, ma non tanto che ho ancora tentato di risolverlo da solo.
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)
Probabilmente, molti di questi dovrebbero essere estratti e messi in una biblioteca comune. Se fosse raggruppato con il pacchetto C2HS, sarebbe perfetto (IMHO il modulo C2HS è stato rimosso un po 'prematuramente).