[Haskell-cafe] Re: help with FFI

Maurí­cio CA mauricio.antunes at gmail.com
Thu Sep 17 19:53:31 EDT 2009


> typedef struct {
> int *a;
> int *b;
> /*lots of stuff
> ...
> */
> int *z;
> } foo;
> int create_foo(foo *f,FILE *file,int x,int y);
> int use_foo(foo *f,int w);
> int destroy_foo(foo *f);

> newtype Foo = Foo ()
> foreign import ccall "static foo.h create_foo"
> c_create_foo :: Ptr (Foo) -> Ptr (CFile) -> CInt -> CInt -> IO CInt
> foreign import ccall "static foo.h use_foo"
> c_use_foo :: Ptr (Foo) -> CInt -> IO CInt
> foreign import ccall "static foo.h destroy_foo"
> c_destroy_foo :: Ptr (Foo) -> IO CInt

Your 'create_foo' is only an initialization function, i.e., it
initializes data in a Foo but do not allocate memory for the data
such pointer points to. So, what you would like to do is something
like this:

import Foreign.Marshall.Alloc

(...)
ptrFoo <- malloc
c_create_foo ptrFoo ptrCFile (...)
(...)
free ptrFoo

Looking at malloc you see:

malloc :: Storable a => IO (Ptr a)

and this gives you the hint: you need to make an
instance of Storable class with your Foo type.
Storable method 'sizeOf' should provide the proper
size to be used in such kind of memory allocation.
(After that, you would probably want to learn
about ForeignPtr, which would call, say, free and
c_destroy_foo when your pointer is not beeing used
anymore.)

Best,
Maurício

P.S.: (Warning: spam promoting my own work.)

If you use my package bindings-common, available in hackage, you
can get that type and instance in a .hsc file by doing this:

#bindings_starttype struct foo
#bindings_stoptype _

But this package is not very popular yet, so
I can't guarantee it's bug free.



More information about the Haskell-Cafe mailing list