module GHC.Dotnet
( Object
, unmarshalObject
, marshalObject
, unmarshalString
, marshalString
, checkResult
) where
import GHC.Prim
import GHC.Base
import GHC.IO
import GHC.IOBase
import GHC.Ptr
import Foreign.Marshal.Array
import Foreign.Marshal.Alloc
import Foreign.Storable
import Foreign.C.String
data Object a
= Object Addr#
checkResult :: (State# RealWorld -> (# State# RealWorld, a, Addr# #))
-> IO a
checkResult fun = IO $ \ st ->
case fun st of
(# st1, res, err #)
| err `eqAddr#` nullAddr# -> (# st1, res #)
| otherwise -> throw (IOException (raiseError err)) st1
unmarshalObject :: Addr# -> Object a
unmarshalObject x = Object x
marshalObject :: Object a -> (Addr# -> IO b) -> IO b
marshalObject (Object x) cont = cont x
marshalString :: String
-> (Addr# -> IO a)
-> IO a
marshalString str cont = withCString str (\ (Ptr x) -> cont x)
unmarshalString :: Addr# -> String
unmarshalString p = unsafePerformIO $ do
let ptr = Ptr p
str <- peekCString ptr
free ptr
return str
raiseError :: Addr# -> IOError
raiseError p = userError (".NET error: " ++ unmarshalString p)