[prev in list] [next in list] [prev in thread] [next in thread] 

List:       haskell
Subject:    Re: [Haskell] using the ffi with callbacks
From:       Taral <taralx () gmail ! com>
Date:       2006-07-21 16:39:56
Message-ID: fa0147d90607210939v37471aa6rad7404543a08e9a8 () mail ! gmail ! com
[Download RAW message or body]

On 7/20/06, Evan Martin <martine@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@gmail.com>
"You can't prove anything."
    -- Gödel's Incompetence Theorem

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic