ForeignPtr's - why can't they be passed directly to foreign
functions?
Brian Hulley
brianh at metamilk.com
Wed Mar 15 06:45:05 EST 2006
Hi -
I've got the beginnings of an API for a GUI system as follows:
data DWindow a
data DEdit a
type Window = DWindow
type Edit a = DWindow (DEdit a)
foreign import ccall duma_init :: IO ()
foreign import ccall duma_run :: IO ()
foreign import ccall duma_release :: FunPtr (Ptr (Window a) -> IO ())
foreign import ccall duma_createEdit :: IO (Ptr (Edit a))
foreign import ccall duma_addTop :: Ptr (Window a) -> IO ()
createEdit :: IO (ForeignPtr (Edit a))
createEdit = do
edit <- duma_createEdit
newForeignPtr duma_release edit
addTop :: ForeignPtr (Window a) -> IO ()
addTop w = withForeignPtr w duma_addTop
This works, but it seems a bit of a pain to have to manually convert between
ForeignPtr's and Ptr's all the time.
In particular, for the definition of addTop, I tried:
foreign import ccall "duma_addTop" addTop :: ForeignPtr (Window a) -> IO ()
but got an error because ForeignPtr's are not allowed as part of the type of
a foreign function. Since the definition of ForeignPtr is just void *, I
wonder why this restriction exists - ie is a ForeignPtr not just the same
address as the corresponding Ptr?
My other question is what happens if I want to have a function that takes
more than one ForeignPtr as argument ie
foreign import ccall duma_test :: Ptr (Window a) -> Ptr (Window a) -> IO ()
test :: ForeignPtr (Window a) -> ForeignPtr (Window a) -> IO ()
test p q = withForeignPtr p (\p' -> withForeignPtr q $ duma_test p')
Is this the only way to achieve this? It seems a bit long-winded and
possibly a bit inefficient...
One other question: if I use forkIO within Haskell, am I right in thinking
that the lightweight concurrent threads are safe to use with my single
threaded C code ie that there is no danger of a thread being preemptively
halted while it is inside a foreign function?
Thanks, Brian.
More information about the Glasgow-haskell-users
mailing list