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:[EMAIL PROTECTED]
Sent: 02 June 2003 10:46
To: [EMAIL PROTECTED]
Subject: Re: Help: writing ffi bindings to a C library


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
   \__/       [EMAIL PROTECTED]
    ^^     http://qrnik.knm.org.pl/~qrczak/

_______________________________________________
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


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

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

_______________________________________________
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to