Help: writing ffi bindings to a C library

Bayley, Alistair Alistair_Bayley@ldn.invesco.com
Wed, 4 Jun 2003 13:16:44 +0100


Thanks. This is very helpful. I'm making much better progress now.

Is alloca the idiomatic technique when you want to create a pointer to a
pointer? Or are there other ways?

Initially I tried to pass a Ptr (Ptr SomeType), but I couldn't because Ptr
has no constructors To create values of type Ptr I must use the functions in
Foreign.Marshal.Alloc (and Foreign.Marshal.Utils). Correct?


-----Original Message-----
From: Marcin 'Qrczak' Kowalczyk [mailto:qrczak@knm.org.pl]
Sent: 02 June 2003 10:46
To: haskell-cafe@haskell.org
Subject: Re: Help: writing ffi bindings to a C library


Dnia pon 2. czerwca 2003 09:58, Bayley, Alistair napisa=B3:

> 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 =3D 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 =3D
   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=20
it should be finalized when it's garbage collected.

You can use hsc2hs to access integer constants, enumeration values and
structs=20
from Haskell, or write C wrappers inline inside Haskell source (e.g. to turn

macros into functions).

--=20
   __("<         Marcin Kowalczyk
   \__/       qrczak@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


*****************************************************************
The information in this email and in any attachments is=20
confidential and intended solely for the attention and use=20
of the named addressee(s). This information may be=20
subject to legal professional or other privilege or may=20
otherwise be protected by work product immunity or other=20
legal rules.  It must not be disclosed to any person without=20
our authority.

If you are not the intended recipient, or a person=20
responsible for delivering it to the intended recipient, you=20
are not authorised to and must not disclose, copy,=20
distribute, or retain this message or any part of it.
*****************************************************************