module System.Glib.FFI (
with,
nullForeignPtr,
maybeNull,
newForeignPtr,
withForeignPtrs,
module Foreign,
module Foreign.C
) where
import System.IO.Unsafe (unsafePerformIO)
import Foreign.C
import qualified Foreign hiding (free)
import Foreign hiding (with, newForeignPtr, free
#if (__GLASGOW_HASKELL__<606)
, withObject
#endif
)
#if (__GLASGOW_HASKELL__>=610)
import qualified Foreign.Concurrent
#endif
with :: (Storable a) => a -> (Ptr a -> IO b) -> IO b
with = Foreign.with
#if (__GLASGOW_HASKELL__>=610)
newForeignPtr :: Ptr a -> FinalizerPtr a -> IO (ForeignPtr a)
newForeignPtr p finalizer
= Foreign.Concurrent.newForeignPtr p (mkFinalizer finalizer p)
foreign import ccall "dynamic"
mkFinalizer :: FinalizerPtr a -> Ptr a -> IO ()
#else
newForeignPtr :: Ptr a -> FinalizerPtr a -> IO (ForeignPtr a)
newForeignPtr = flip Foreign.newForeignPtr
#endif
nullForeignPtr :: ForeignPtr a
nullForeignPtr = unsafePerformIO $ newForeignPtr_ nullPtr
withForeignPtrs :: [ForeignPtr a] -> ([Ptr a] -> IO b) -> IO b
withForeignPtrs fptrs body = do
result <- body (map unsafeForeignPtrToPtr fptrs)
mapM_ touchForeignPtr fptrs
return result
maybeNull :: (IO (Ptr a) -> IO a) -> IO (Ptr a) -> IO (Maybe a)
maybeNull marshal genPtr = do
ptr <- genPtr
if ptr == nullPtr
then return Nothing
else do result <- marshal (return ptr)
return (Just result)