greencard and callbacks

I realize that I myself might have already asked this question to some
of you, but I am really confused now. Can I have some opinion on "what
is the right way to implement callbacks from C to haskell"? Will I have
to learn the FFI and stop it, or is there some tool to automate the
process? I need to bind a single function which takes a record of
callbacks, and that's all.
Can greencard support callbacks? If yes, can someone provide a simple
example? I thought to do:
import Foreign.GreenCard
%#include

On Thursday 06 May 2004 13:36, Vincenzo aka Nick Name wrote:
Can greencard support callbacks? If yes, can someone provide a simple example?
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. I just renounced to the [unique] tag and having optionally null fields in a record, but now I have another problem: === typedef int (*readlinkT)([in,string] const char *, [size_is(size),string,out] char * buf, [hide] unsigned int size); ghc -package hdirect -fglasgow-exts HSFuse.hs -c HSFuse.hs:190: Variable not in scope: `buf' === The offending line is, in the following fragment of code, the one beginning with "let size =", of course there is no "buf", if the argument is called "out_buf"! === wrap_ReadlinkT readlinkT_meth anon1 out_buf size = do anon1 <- HDirect.unmarshallString anon1 (res__buf, res__o_ReadlinkT) <- readlinkT_meth anon1 size let size = (Prelude.fromIntegral (Prelude.length buf) :: Data.Word.Word32) buf <- HDirect.marshallString buf HDirect.writePtr (Foreign.Ptr.castPtr out_buf) res__buf Prelude.return (res__buf, res__o_ReadlinkT) === Now, if I may ask the final question: is it me not understanding how I should do things, or is hdirect completely broken and I am the only one not knowing this? What tool should I use to write a libfuse binding? Is plain FFI my only hope? Thanks Vincenzo

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))
participants (2)
-
Alastair Reid
-
Vincenzo aka Nick Name