
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/