[Haskell-cafe] Is hdirect just broken?

Alastair Reid alastair at reid-consulting-uk.ltd.uk
Thu May 6 19:30:57 EDT 2004

> Ok, I finally found Alistair Reid's tutorial, which I forgot to read
> again, and well, I see that greencard does not support callbacks. My
> alternatives are plain FFI and hdirect.

If it is just one callback function, I'd strongly consider just using the 
plain ffi interface since you'll have less tools to learn that way.

One thing to watch is that Hugs supports exporting function pointers but not 
static functions.  So you have to write some (simple) initialization code 
that turns a Haskell function into a C function pointer and hands that to C 
and your C code (may) have to have a static callback function which calls 
your freshly created function pointer.

The attached code (hugs98/tests/ffi/Sin.hs) should get you going.

Alastair Reid

-- !!! Testing static, dynamic and wrapped import of trig function

-- Imports kept minimal to avoid pulling in Storable and other
-- things which use even more ffi.
import IOExts( unsafePerformIO )
import Ptr( FunPtr, freeHaskellFunPtr )

tests = do

  putStrLn "\nTesting sin==mysin (should return lots of Trues)"
  print (testSin sin mysin)

  putStrLn "\nTesting sin==dynamic_sin (should return lots of Trues)"
  print (testSin sin (dyn_sin sin_addr))

  putStrLn "\nTesting sin==IO wrapped_sin (should return lots of Trues)"
  sin_addr2 <- wrapIO (return . sin)
  print (testSin sin (unsafePerformIO . (dyn_sinIO sin_addr2)))
  freeHaskellFunPtr sin_addr2

  putStrLn "\nTesting sin==Id wrapped_sin (should return lots of Trues)"
  sin_addr3 <- wrapId sin
  print (testSin sin (dyn_sin sin_addr3))
  freeHaskellFunPtr sin_addr3

testSin f g = [ (f x == g x) | x <- [0,0.01 .. 1] ]

foreign import ccall "math.h sin" mysin :: Double -> Double
foreign import ccall "dynamic" dyn_sin :: FunPtr (Double -> Double) -> (Double 
-> Double)
foreign import ccall "dynamic" dyn_sinIO :: FunPtr (Double -> IO Double) -> 
(Double -> IO Double)
foreign import ccall "math.h &sin" sin_addr :: FunPtr (Double -> Double)
foreign import ccall "wrapper" wrapId :: (Double -> Double) -> IO (FunPtr 
(Double -> Double))
foreign import ccall "wrapper" wrapIO :: (Double -> IO Double) -> IO (FunPtr 
(Double -> IO Double))

More information about the Haskell-Cafe mailing list