[Haskell-cafe] [ANNOUNCE] Bindings for libguestfs

Peter Gammie peteg42 at gmail.com
Wed May 13 09:15:24 EDT 2009


Richard,

I remember having similar problems to you when trying to use the FFI.  
The following comments are suggestions as to what helps in practice,  
and not a claim that the situation can't be improved.

On 13/05/2009, at 8:40 PM, Richard W.M. Jones wrote:

> Specific things would be:
>
> Recommendation to use 'throwDyn' to throw exceptions, yet this
> function doesn't exist in my version of GHC.  In fact, none of the
> code here:
>
> http://www.haskell.org/haskellwiki/FFICookBook#Raising_and_handling_exceptions
>
> works in GHC at all, as far as I could tell.

The shifting exceptions story is a PITA. Compatibility is the price of  
progress.

> No good examples available on how to use ForeignPtr.  Yet I'd argue
> that almost any non-trivial modern C library bindings will have some
> concept of an opaque object, so this is the most vital example.  (The
> examples in RWH ch 17 weren't enough for me).

I'd suggest you download a mature library binding close to what you  
want to do and ape that. For example:

1. got lots of C structures? look at a GTK binding.
2. got a fairly imperative API? look at a database binding, or HOpenGL.
3. got a fairly pure API? look at a BDD or numerical package binding.

and so forth.

The FFI itself is intended to be minimal, just enough to do the job.  
The idea was that extra tools (most prominently hsc2hs and c2hs,  
historically greencard) would support large bindings.

It's funny you say "opaque object". ForeignPtr only handles pointers.  
In one library I relied on, the opaque objects were represented with  
ints. It'd be nice to track arbitrary values the way that ForeignPtr  
tracks C pointers.

> I'd really like to know what parameters and return types are
> permissible for 'foreign import ccall' statements.  By trial and error
> I found out.

Is the FFI spec unclear on this point?

> How do I convert to/from booleans?

Can you use the methods of the Enum class?

> How do I really use C structures?  Real examples, please.

I'd suggest looking into c2hs. Even if you don't use it, the code it  
generates is quite illuminating, especially how it pushes values  
between C and Haskell.

> How can I free a C string that is returned from a 'caller frees' C
> function?  Does Foreign.Marshall.Alloc.free work for this?

This is tricky. Rather than give you a definite answer, I'd suggest  
you check with the FFI spec.

IIRC in principle the FFI's malloc/free could be distinct from those  
in C land, but in practice (GHC) they coincide.

> Again, reflecting my own inexperience with Haskell, I found
> 'withCString', 'maybeWith', 'withMany', 'withArray0' etc to be both
> undocumented and extremely confusing to use.

They're documented in the FFI spec. Granted using them is not  
necessarily intuitive, which is where looking at existing code might  
help.

> How do I specify a 64 bit int?  Using 'Int64#' just causes syntax
> errors.

Did you look into the Data.Word library?

> What's a good emacs editing mode for Haskell code?  My emacs thinks
> Haskell code is LISP ...

There's been a Haskell mode for at least a decade now. It's packaged  
with every emacs I've used in the past few years.

http://www.haskell.org/haskell-mode/

To editorialise a bit, I think the original FFI spec is very clearly  
written, and the contradictions you allude to lie in fact in the more  
recent wiki writeups; the Haskell specs are lucid and intended to be  
usable, and not just by the compiler writers.

One last gotcha: be very careful about strictness if you're trying to  
graft a pure API onto the library.

Hope this helps!

cheers
peter


More information about the Haskell-Cafe mailing list