[Haskell-cafe] [ANNOUNCE] Bindings for libguestfs
peteg42 at gmail.com
Wed May 13 09:15:24 EDT 2009
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:
> works in GHC at all, as far as I could tell.
The shifting exceptions story is a PITA. Compatibility is the price of
> 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
> How do I specify a 64 bit int? Using 'Int64#' just causes syntax
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.
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!
More information about the Haskell-Cafe