Haskell FFI - How to handle C functions that accept or return structs instead of pointers to structs?
c, ffi, haskell
Solution
The FFI doesn't support arbitrary pass by value Haskell storable types.
You may only pass values of type (and some of these are pointers):
Int#, Word#,
Char#,
Float#, Double#,
Addr#,
StablePtr# a, MutableByteArray#, ForeignObj#, and ByteArray#.
So, to pass a structure you must wrap the call via a C wrapper; which takes a pointer and passes its value to the C function you wish to actually call.
A recent GHC extension allows for "primop" imports -- which bypass the FFI mechanism and support arbitrary calling conventions and passing structures via unboxed tuples. E.g.
foreign import prim "ITCHv41_run"
parseITCHv41# :: Addr# -> Word#
-> (# Int#, Word#, Word#, Word#, Word#, Word# #)
You can use these to do tricky low level stuff like this.
Problem
Of course the answer is to somehow pass/take a contiguous block of memory, so the question is more about how to do that. For now I could still avoid the issue by writing wrapper functions on the C side, but that's not much of a permament solution.