[Haskell] using the ffi with callbacks

Evan Martin martine at danga.com
Thu Jul 20 21:05:04 EDT 2006


On 7/21/06, Taral <taralx at gmail.com> wrote:
> On 7/20/06, Evan Martin <martine at danga.com> wrote:
> > The tricky part is that to pass in Haskell functions, I need to use
> > the FFI "wrapper" import, which means I need to later free them.  But
> > the only place I can free them is within the "free" callback, and I've
> > just discovered this isn't allowed!
>
> free_fcn is normally a static function. It shouldn't need to free
> itself. I'm thinking something like:
>
> type Callback = StablePtr (Callback, DataStructure)-> IO ()
> foreign import ccall "wrapper" mkCallback :: Callback -> IO (FunPtr Callback)
> foreign export "free_fcn" free_fcn :: Callback
>
> free_fcn sp = do
>     (cb, ds) <- deRefStablePtr sp
>     freeStablePtr sp
>     freeHaskellFunPtr cb

Ah, I think I see.  I hadn't looked at "export", but a static function
does seem like what I want.

But I also don't quite understand how the typing works out.
For example, can you use StablePtr directly with FFI functions, or do
they require you casting through Ptr?

/* C code, as before but with a typedef for clarity */
typedef void (*Callback)(void*);
void register_callback(
   Callback callback_fcn,
   void *callback_data,
   Callback free_fcn);

-- importing this function.
-- you had:
type Callback = StablePtr (Callback, DataStructure)-> IO ()

foreign import ccall register_callback ::
  FunPtr Callback ->   -- because mkCallback gives a FunPtr
  Ptr (Callback, DataStructure) ->  -- or StablePtr?
  Callback ->  -- but here don't we again need a FunPtr?
  IO ()


More information about the Haskell mailing list