> From: Antony Courtney [mailto:[EMAIL PROTECTED]] > > While the FFI spec. is excellent, I'd really like to see a companion > document with real examples of how to use the FFI for the > easy, obvious > kinds of library interfacing tasks that are likely to arise > in practice.
There are quite a few examples in fptools/libraries in the CVS repository. These libraries all use the FFI: IO, Time, Directory, CPUTime, Network.Socket, Text.Regex.Posix, and the new System.Posix stuff. I agree, it would be nice to have some introductory material on programming the FFI "for real", though. > Such examples would hopefully help answer things like the following > rather naieve question that I have: > > Is there a particular "best" way to deal with C functions that take > "lightweight" struct values (or pointers to such structs), To answer your question, there are several choices, each with its own advantages and disadvantages. You'll find examples of these in the libraries I mentioned above. I'm assuming that you want to use the FFI directly (possibly with help from c2hs or hsc2hs), rather than use one of the higher level tools. 1. Fully marshal the structure to/from Haskell. The best way to do this is to write a Haskell datatype for the structure, and define a Storable instance for it. You can use a tool to help you write the Storable instance in a portable way: hsc2hs and c2hs are good for this. Full marshalling is likely to be a good choice when you want to do lots of manipulation of the structure on the Haskell side. 2. Keep the structure in its C representation, and manipulate the structure using peek/poke in Haskell. This is a good choice if manipulation on the Haskell side is limited, for example if a single field is required to be extracted, and you don't want to marshal the entire struct into Haskell. Also, sometimes the representation is partially abstract on the C side (many C structs in POSIX for example are only partially specified by the standard), so fully marshalling it is not an option. If the lifetime of the struct is well-known and scoped (such as across a single call to a foreign function), then the MarshalAlloc.alloca family of functions can be used to allocate it. Again, to portably peek/poke individual fields, you'll probably find that hsc2hs or c2hs are useful. If the lifetime of the structure does not work well with alloca, or you want it to be garbage collected, then use a ForeignPtr instead. The new functions mallocForeignPtr and mallocForeignPtrBytes provide for this kind of allocation, and will perform better in GHC than using explicit malloc/free. Hope this helps, Simon _______________________________________________ FFI mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/ffi