
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