Foreign Function Interface

Use ForeignPtr with finalizers for C-allocated resources. Use safe calls (the default) when C may call back into Haskell or take a long time; unsafe is faster for short calls.

Tools: hsc2hs (struct offsets and constants), c2hs, inline-c (write C inline in Haskell), hs-bindgen (newer binding generator efforts). Calling Rust is possible via its C ABI.

{-# LANGUAGE ForeignFunctionInterface, CApiFFI #-}
module Main where

import Foreign
import Foreign.C.Types
import Foreign.C.String

-- Import C functions
foreign import ccall unsafe "math.h sin" c_sin :: CDouble -> CDouble
foreign import ccall "string.h strlen" c_strlen :: CString -> IO CSize
foreign import capi "stdlib.h abs" c_abs :: CInt -> CInt

-- Pure wrapper
fastSin :: Double -> Double
fastSin = realToFrac . c_sin . realToFrac

main :: IO ()
main = do
  print (fastSin 1.0)
  len <- withCString "Haskell" c_strlen
  print len                                   -- 7
  print (c_abs (-5))

  -- Manual memory with alloca/malloc and Storable
  allocaArray 5 $ \ptr -> do
    pokeArray ptr [1, 2, 3, 4, 5 :: CInt]
    xs <- peekArray 5 ptr
    print (sum xs)

-- Export a Haskell function to C
square :: CInt -> CInt
square x = x * x
foreign export ccall square :: CInt -> CInt