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.
*****************************************************************