Help: writing ffi bindings to a C library
Marcin 'Qrczak' Kowalczyk
qrczak@knm.org.pl
Mon, 2 Jun 2003 11:45:43 +0200
Dnia pon 2. czerwca 2003 09:58, Bayley, Alistair napisał:
> Yes, I had considered this (writing an abstraction layer in C). I have
> decided initially to try doing it in Haskell, because I thought that
> Haskell would be a better choice for writing abstraction layers (not as
> verbose as C).
You can write it in Haskell too and I would recommend that - unless the C
library uses some passing convention Haskell cannot handle (e.g. passing
structs by value, or having variable argument count, or relying heavily on
macros).
> Getting back to my question, can I use functions that take twice-deref'ed
> pointers as args? This is a function that effectively returns some of its
> work in "out" arguments
Sure. You can use libraries documented in the Haskell FFI proposal.
> e.g. a C function like this:
>
> int someCFunction(SomeType **ptrptr, int i)
>
> (It would create an opaque structure and point *ptrptr at it. If it fails
> then it would return a negative value.)
>
> Is it simply a case of declaring it like this (in ghc):
> > data SomeType
> > type SomeTypeRef = Ptr SomeType
> > foreign import ccall "blah.h someCFunction" someCFunction ::
> > Ptr SomeTypeRef -> Int -> Int
foreign import ccall "blah.h someCFunction" someCFunction ::
Ptr SomeTypeRef -> CInt -> IO CInt
haskellWrapper :: Int -> IO (Maybe SomeTypeRef)
haskellWrapper arg =
alloca $ \ptr -> do
res <- someCFunction ptr (fromIntegral arg)
if res < 0 then return Nothing else liftM Just (peek ptr)
You can raise an IO error instead. You can wrap the result in a ForeignPtr if
it should be finalized when it's garbage collected.
You can use hsc2hs to access integer constants, enumeration values and structs
from Haskell, or write C wrappers inline inside Haskell source (e.g. to turn
macros into functions).
--
__("< Marcin Kowalczyk
\__/ qrczak@knm.org.pl
^^ http://qrnik.knm.org.pl/~qrczak/