[Haskell] using the ffi with callbacks

Taral taralx at gmail.com
Fri Jul 21 12:39:56 EDT 2006


On 7/20/06, Evan Martin <martine at danga.com> wrote:
> 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?

Yes. You can use any Storable with FFI functions, as far as I know.
StablePtr is explicitly designed for this purpose, allowing you to
"export" an object to the FFI while keeping the GC apprised of its use
by external code.

> /* 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 ()

Oh, right. Try:

type CallbackData = StablePtr (CallbackData, DataStructure)
type Callback = CallbackData -> IO ()

foreign import ccall register_callback :: FunPtr Callback ->
CallbackData -> FunPtr Callback -> IO ()

You get that FunPtr by the import/export trick described by Anatoly or
you can just construct the FunPtr in main or an unsafePerformIO CAF.
(We need a constructor syntax for top-level objects requiring IO!)

-- 
Taral <taralx at gmail.com>
"You can't prove anything."
    -- Gödel's Incompetence Theorem


More information about the Haskell mailing list