# The FFI library in nhc98

This document sketches the NHC.FFI library in nhc98. It is based very closely on the proposed standard Foreign Function Interface libraries. The main difference from the proposed standard is that it collects all the proposed library functions into a single module.

### The NHC.FFI library

    module NHC.FFI
       -------------------------------------------------------------------
       -- {Int,Word}{8,16,32,64} are abstract and instances of Eq, Ord,
       --   Num, Bounded, Real, Integral, Ix, Enum, Read, Show
       -------------------------------------------------------------------
      ( Int8,  Int16,  Int32,  Int64
      , Word8, Word16, Word32, Word64

       -------------------------------------------------------------------
       -- `Addr' is now obsolete - use `Ptr a' instead.
       -------------------------------------------------------------------
      , Addr                  -- abstract, instance of: Eq, Ord, Enum, Show
      , nullAddr              -- :: Addr
      , plusAddr              -- :: Addr -> Int -> Addr

       -------------------------------------------------------------------
       -- `Ptr a' is a C pointer value.
       -------------------------------------------------------------------
      , Ptr(..)		-- abstract, instance of: Eq, Ord, Enum, Show
      , nullPtr		-- :: Ptr a
      , castPtr		-- :: Ptr a -> Ptr b
      , plusPtr		-- :: Ptr a -> Int -> Ptr b
      , alignPtr		-- :: Ptr a -> Int -> Ptr a
      , minusPtr		-- :: Ptr a -> Ptr b -> Int

       -------------------------------------------------------------------
       -- `FunPtr a' is a C function pointer value.
       -------------------------------------------------------------------
      , FunPtr              -- abstract, instance of: Eq, Ord, Enum, Show
      , nullFunPtr          -- :: FunPtr a
      , castFunPtr          -- :: FunPtr a -> FunPtr b
      , castFunPtrToPtr     -- :: FunPtr a -> Ptr b
      , castPtrToFunPtr     -- :: Ptr a -> FunPtr b

       -------------------------------------------------------------------
       -- The `Storable' class.
       -------------------------------------------------------------------
      , Storable
          ( sizeOf            -- :: a -> Int
          , alignment         -- :: a -> Int
          , peekElemOff       -- :: Ptr a -> Int      -> IO a
          , pokeElemOff       -- :: Ptr a -> Int -> a -> IO ()
          , peekByteOff       -- :: Ptr b -> Int      -> IO a
          , pokeByteOff       -- :: Ptr b -> Int -> a -> IO ()
          , peek              -- :: Ptr a             -> IO a
          , poke              -- :: Ptr a        -> a -> IO ()
          , destruct)         -- :: Ptr a             -> Io ()

       -------------------------------------------------------------------
       -- `ForeignObj' is now obsolete - use `ForeignPtr a' instead.
       -------------------------------------------------------------------
      , ForeignObj            -- abstract, instance of: Eq
      , newForeignObj         -- :: Addr -> IO () -> IO ForeignObj
      , makeForeignObj        -- :: Addr -> IO () -> IO ForeignObj  -- OBSOLETE
      , foreignObjToAddr      -- :: ForeignObj -> Addr
    #if !defined(TRACING)
       ,freeForeignObj        -- :: ForeignObj -> IO ()
    #endif
      , withForeignObj        -- :: ForeignObj -> (Addr -> IO a) -> IO a
      , touchForeignObj       -- :: ForeignObj -> IO ()

       -------------------------------------------------------------------
       -- `ForeignPtr a' is a C pointer value with an associated finaliser.
       -------------------------------------------------------------------
      , ForeignPtr                -- abstract, instance of: Eq
      , newForeignPtr             -- :: Ptr a -> IO () -> IO (ForeignPtr a)
    -- , addForeignPtrFinalizer   -- :: ForeignPtr a -> IO () -> IO ()
      , touchForeignPtr           -- :: ForeignPtr a -> IO ()
      , withForeignPtr            -- :: ForeignPtr a -> (Ptr a -> IO b) -> IO b
      , foreignPtrToPtr           -- :: ForeignPtr a -> Ptr a
      , castForeignPtr            -- :: ForeignPtr a -> ForeignPtr b

       -------------------------------------------------------------------
       -- `StablePtr a' is a Haskell value passed to the foreign land.
       -------------------------------------------------------------------
    #if !defined(TRACING)
      , StablePtr             -- abstract
      , newStablePtr          -- :: a -> IO (StablePtr a)
      , makeStablePtr         -- :: a -> IO (StablePtr a)	-- OBSOLETE
      , deRefStablePtr        -- :: StablePtr a -> IO a
      , freeStablePtr         -- :: StablePtr a -> IO ()
      , stablePtrToAddr       -- :: StablePtr a -> Addr	-- OBSOLETE
      , addrToStablePtr       -- :: Addr -> StablePtr a	-- OBSOLETE
      , castStablePtrToPtr  -- :: StablePtr a -> Ptr ()
      , castPtrToStablePtr  -- :: Ptr () -> StablePtr a
    #endif

       -------------------------------------------------------------------
       -- `unsafePerformIO' is so commonly used, it should be exported.
       -------------------------------------------------------------------
      , unsafePerformIO	-- :: IO a -> a

       -------------------------------------------------------------------
       -- nhc98's `PackedString' is a heap-allocated packed array of characters.
       -------------------------------------------------------------------
      , PackedString	-- abstract
      , toCString		-- :: String  -> PackedString
      , fromCString		-- :: PackedString -> String

       -------------------------------------------------------------------
       -- `CString' is a C-allocated C packed array of characters.
       -------------------------------------------------------------------
      , CString             -- = Ptr CChar
      , CStringLen          -- = (CString, Int)
      , peekCString         -- :: CString    -> IO String
      , peekCStringLen      -- :: CStringLen -> IO String
      , newCString          -- :: String -> IO CString
      , newCStringLen       -- :: String -> IO CStringLen
      , withCString         -- :: String -> (CString    -> IO a) -> IO a
      , withCStringLen      -- :: String -> (CStringLen -> IO a) -> IO a
      , castCharToCChar     -- :: Char -> CChar
      , castCCharToChar     -- :: CChar -> Char

       -------------------------------------------------------------------
       -- nhc98's `CError' helps to build meaningful error messages.
       -------------------------------------------------------------------
      , getErrNo		-- :: IO Int
      , mkIOError		-- :: String -> Maybe FilePath -> Maybe Handle
    			--      -> Int -> IOError
      , throwIOError	-- :: String -> Maybe FilePath -> Maybe Handle
    			--      -> Int -> IO a
       -------------------------------------------------------------------
       -- Various `CTypes'.
       -------------------------------------------------------------------
      , CChar(..)	, CSChar(..)	, CUChar(..)
      , CShort(..)	, CUShort(..)
      , CInt(..)	, CUInt(..)
      , CLong(..)	, CULong(..)
      , CLLong(..)	, CULLong(..)
      , CFloat(..)	, CDouble(..)	, CLDouble(..)
       -------------------------------------------------------------------
       -- `CTypesExtra'.
       -------------------------------------------------------------------
      , CPtrdiff(..)	, CSize(..)	, CWchar(..)
      , CSigAtomic(..)	, CClock(..)	, CTime(..)
      , CFile		, CFpos		, CJmpBuf

       -------------------------------------------------------------------
       -- `MarshalAlloc' provides memory allocation routines.
       -------------------------------------------------------------------
      , malloc            -- :: Storable a =>        IO (Ptr a)
      , mallocBytes       -- ::               Int -> IO (Ptr a)
      , alloca            -- :: Storable a =>        (Ptr a -> IO b) -> IO b
      , allocaBytes       -- ::               Int -> (Ptr a -> IO b) -> IO b
      , reallocBytes      -- :: Ptr a -> Int -> IO (Ptr a)
      , free              -- :: Ptr a -> IO ()

       -------------------------------------------------------------------
       -- `MarshalArray' provides bulk memory allocation/storage routines.
       -------------------------------------------------------------------
      , mallocArray     -- :: Storable a => Int -> IO (Ptr a)
      , mallocArray0    -- :: Storable a => Int -> IO (Ptr a)
      , allocaArray     -- :: Storable a => Int -> (Ptr a -> IO b) -> IO b
      , allocaArray0    -- :: Storable a => Int -> (Ptr a -> IO b) -> IO b
      , reallocArray    -- :: Storable a => Ptr a -> Int -> IO (Ptr a)
      , reallocArray0   -- :: Storable a => Ptr a -> Int -> IO (Ptr a)
      , peekArray       -- :: Storable a =>         Int -> Ptr a -> IO [a]
      , peekArray0      -- :: (Storable a, Eq a) => a   -> Ptr a -> IO [a]
      , pokeArray       -- :: Storable a =>      Ptr a -> [a] -> IO ()
      , pokeArray0      -- :: Storable a => a -> Ptr a -> [a] -> IO ()
      , newArray        -- :: Storable a =>      [a] -> IO (Ptr a)
      , newArray0       -- :: Storable a => a -> [a] -> IO (Ptr a)
      , withArray       -- :: Storable a =>      [a] -> (Ptr a -> IO b) -> IO b
      , withArray0      -- :: Storable a => a -> [a] -> (Ptr a -> IO b) -> IO b
      , destructArray   -- :: Storable a =>         Int -> Ptr a -> IO ()
      , destructArray0  -- :: (Storable a, Eq a) => a   -> Ptr a -> IO ()
      , copyArray       -- :: Storable a => Ptr a -> Ptr a -> Int -> IO ()
      , moveArray       -- :: Storable a => Ptr a -> Ptr a -> Int -> IO ()
      , lengthArray0    -- :: (Storable a, Eq a) => a -> Ptr a -> IO Int
      , advancePtr      -- :: Storable a => Ptr a -> Int -> Ptr a

       -------------------------------------------------------------------
       -- `MarshalUtils' provides utilities for basic marshalling.
       -------------------------------------------------------------------
      , with           -- :: Storable a => a -> (Ptr a -> IO b) -> IO b
      , new            -- :: Storable a => a -> IO (Ptr a)
      , fromBool       -- :: Num a => Bool -> a
      , toBool         -- :: Num a => a -> Bool
      , maybeNew       -- :: (      a -> IO (Ptr a))
                       -- -> (Maybe a -> IO (Ptr a))
      , maybeWith      -- :: (      a -> (Ptr b -> IO c) -> IO c)
                       -- -> (Maybe a -> (Ptr b -> IO c) -> IO c)
      , maybePeek      -- :: (Ptr a -> IO        b )
                       -- -> (Ptr a -> IO (Maybe b))
      , withMany       -- :: (a -> (b -> res) -> res) -> [a] -> ([b] -> res) -> res
      , copyBytes      -- :: Ptr a -> Ptr a -> Int -> IO ()
      , moveBytes      -- :: Ptr a -> Ptr a -> Int -> IO ()

       -------------------------------------------------------------------
       -- `MarshalError' provides utilities for basic error-handling.
       -------------------------------------------------------------------
      , throwIf        -- :: (a -> Bool) -> (a -> String) -> IO a       -> IO a
      , throwIf_       -- :: (a -> Bool) -> (a -> String) -> IO a       -> IO ()
      , throwIfNeg     -- :: (Ord a, Num a) => (a -> String) -> IO a    -> IO a
      , throwIfNeg_    -- :: (Ord a, Num a) => (a -> String) -> IO a    -> IO ()
      , throwIfNull    -- :: String  -> IO (Ptr a) -> IO (Ptr a)
      , void           -- IO a -> IO ()

      )

The latest updates to these pages are available on the WWW from `http://www.cs.york.ac.uk/fp/nhc98/`

2001.11.27
York Functional Programming Group