ForeignPtr's - why can't they be passed directly to foreign functions?

Brian Hulley brianh at
Wed Mar 15 11:39:43 EST 2006

Esa Ilari Vuokko wrote:
> On 3/15/06, Brian Hulley <brianh at> wrote:
>> [snip]
> (Not directly related, but maybe useful to know)
> Stricly speaking, asynchronous exception may occur in between, and
> this
> code should in fact be "surrounded" by block to prevent resource
> leaks.
> createEdit = block $ do
>  edit <- duma_createEdit
>  newForeignPtr duma_release edit

Thanks for pointing this out. I also realised it is simpler to write using 
 >>= as:

createEdit = block $ duma_createEdit >>= newForeignPtr duma_release

>> 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?
> First, Ptr and ForeignPtr are totally diffrent beasts.  Ptr is just
> plain address,
> [snip]
> Reality: There is no magic in ForeignPtr for ffi calls, and hence
> it's just like any other haskell object (like any other boxed value,
> anyway) - the parameter given to the function might be last reference
> to the value, and it might be optimised/thrown away just before the
> actual function call, get garbage collected and resource might be
> free'd.  Which certainly isn't what you want.

I'd forgotten that Haskell function calls are quite different to C (where 
temp objects for example always survive till the call returns since C 
doesn't have tail call optimization)

Thanks, Brian. 

More information about the Glasgow-haskell-users mailing list