[Haskell-cafe] Re: Can my type be allowed as return type in FFI?
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 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.
More information about the Haskell-Cafe