
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ł:
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/ _______________________________________________ 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 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. *****************************************************************

Dnia śro 4. czerwca 2003 14:16, Bayley, Alistair napisał:
Is alloca the idiomatic technique when you want to create a pointer to a pointer? Or are there other ways?
It's an idiomatic technique for creating a temporary C object whose lifetime is explicit. You could use malloc, but then you have to remember to free it. alloca is an analogue of local variables in C (they are really allocated on GHC heap in GHC or with malloc in other implementations).
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?
More or less yes (there is nullPtr, you can 'foreign import' pointers to global C variables, you can return pointers from imported C functions if it makes sense...). -- __("< Marcin Kowalczyk \__/ qrczak@knm.org.pl ^^ http://qrnik.knm.org.pl/~qrczak/
participants (2)
-
Bayley, Alistair
-
Marcin 'Qrczak' Kowalczyk