extended foreign decls

Marcin 'Qrczak' Kowalczyk qrczak at knm.org.pl
Wed Dec 6 14:42:45 EST 2000

Wed, 6 Dec 2000 16:35:51 +0000, malcolm-ffi at cs.york.ac.uk <malcolm-ffi at cs.york.ac.uk> pisze:

> I *really* *really* want to be able to insert small snippets of
> foreign code into the source of a Haskell module.

You can do it with hsc2hs:

foreign import "hs_PyTuple_Check" unsafe
    tupleCheck :: Object -> Bool
#def inline HsBool hs_PyTuple_Check (PyObject *o) \
{return PyTuple_Check (o);}

The C wrapper was needed here because PyTuple_Check is a macro.

Inside the body there is no need of \ at the end of every line.
Until the matching } everything belongs to the #def.

> I know that it is always possible to write a small .c file and
> compile and link it in separately, but with the new FFI that now
> seems to necessitate writing an additional .h file as well.

hsc2hs writes the .h and .c files for you. It knows how to extract
a declaration or prototype from a definition of a function (inline
or not), variable, struct and typedef. You have to compile and link
the .c file yourself.

> For instance, in the new FFI I often want to do something like
>     foreign code { #include <dirent.h> }

Includes are handled separately. You write

#include <dirent.h>

and it gets included where needed: into the temporary C program
which outputs the Haskell source, in the compiled Haskell module if
compiling via C, and into the .h file if it was generated because
a #def was present.

>     foreign code C {
>       char *readdirent (DIR*d) {
>         struct dirent *e;
>         e = readdir(d);
>         return e->d_name;
>       }
>     }

With hsc2hs you don't have to write such wrappers for all fields.
    (#peek struct dirent, d_name)
is an expression which can be used as having the type
    Ptr a -> IO (Ptr CChar)

You have to ensure that its usage allows to infer the right type for
the result. It is overloaded on Storable.

> As people have pointed out, we need to avoid being totally C-centric,
> which is why there needs to be a language identifier attached.

hsc2hs is of course C centric, but for another language simply
a different preprocessor would be used.

Anyone wants to design hsc++2hs? :-)  But currently you would have
to write extern "C" wrappers for all native C++ functions, methods,
constructors, destructors, conversions, casts through virtual

 __("<  Marcin Kowalczyk * qrczak at knm.org.pl http://qrczak.ids.net.pl/
  ^^                      SYGNATURA ZASTÊPCZA

More information about the FFI mailing list