{-# OPTIONS_GHC -fno-implicit-prelude #-} ----------------------------------------------------------------------------- -- | -- Module : GHC.Dotnet -- Copyright : (c) sof, 2003 -- License : see libraries/base/LICENSE -- -- Maintainer : cvs-ghc@haskell.org -- Stability : internal -- Portability : non-portable (GHC extensions) -- -- Primitive operations and types for doing .NET interop -- ----------------------------------------------------------------------------- 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 -- ToDo: attach finaliser. unmarshalObject :: Addr# -> Object a unmarshalObject x = Object x marshalObject :: Object a -> (Addr# -> IO b) -> IO b marshalObject (Object x) cont = cont x -- dotnet interop support passing and returning -- strings. marshalString :: String -> (Addr# -> IO a) -> IO a marshalString str cont = withCString str (\ (Ptr x) -> cont x) -- char** received back from a .NET interop layer. unmarshalString :: Addr# -> String unmarshalString p = unsafePerformIO $ do let ptr = Ptr p str <- peekCString ptr free ptr return str -- room for improvement.. raiseError :: Addr# -> IOError raiseError p = userError (".NET error: " ++ unmarshalString p)