[Haskell-cafe] Re: Can my type be allowed as return type in FFI?

Duncan Coutts duncan.coutts at worc.ox.ac.uk
Wed Dec 10 12:18:53 EST 2008


On Wed, 2008-12-10 at 14:17 -0200, Mauricio wrote:
> > > > foreign import "nameOfFunction" nameOfFunction
>  > > >  :: IO MyType
>  > >
>  > > > Is it possible to write a  new MyType and make it allowed as
>  > > > a  return  type from  foreign  functions?   Is changing  the
>  > > > compiler the only way to do that?
> 
>  > > Of course you're  not really returning a MyType  but a pointer
>  > > to one. (...)
> 
> This would  solve half my problem.  Can I always  trust that? I've
> been told before  that everytime a C function  returns a struct it
> is actually  returning a pointer, but  I wasn't able  to find that
> written  in stone  so that  I can  trust it  to be  valid anywhere
> Haskell will run and for any return type (like a struct containing
> just a char, for instance).

Sorry, I'm not talking about how C implements passing structures to
functions. The Haskell FFI can only bind functions that pass structures
by pointer, not by value. So if you've got a C function that passes them
by value then you need to write a wrapper function in C and bind to
that.

That way you end up with a pointer on the Haskell side.

> How does  that pointer work?  My  code didn't provide it  to the C
> function, so, I believe I  don't have to deallocate it. Where does
> the memory  it points to live?   Did Haskell FFI  engine gave that
> pointer to  the C  function? How  much time is  it going  to live?
> Enough so I can 'peek' it?

You explicitly pass the pointer and typically you manage the allocation
and de-allocation in Haskell using functions from the Foreign.* modules.

There is no magic. You have to manage all the allocation, writing and
object lifetimes explicitly. The Foreign.* modules provide many
convenience functions that make this simpler in many cases.

> Nice. It  shows unsafePerformIO. Some  functions returning structs
> are  side effect  free.  I'm  writing bindings  I want  to  put on
> hackage,  so what  do  you think  would  fit better  the taste  of
> Haskell  programmers:  pure  functions  using  unsafePerformIO  or
> IO functions?

If the C function is genuinely pure apart from having to allocate and
de-allocate temporary objects (and you treat all such objects by value
using Storable) then it's ok to make it pure in Haskell using
unsafePerformIO. If it mutates any input parameters or uses objects
managed by reference using ForeignPtr then it's not ok. So it really
depends on what the C code is doing.

Duncan



More information about the Haskell-Cafe mailing list