9.2. Writing Haskell interfaces to C code: hs2c

The hs2c command can be used to automate some parts of the process of writing Haskell bindings to C code. It reads an almost-Haskell source with embedded special constructs, and outputs a real Haskell file with these constructs processed, based on information taken from some C headers. The extra constructs deal with accessing C data from Haskell.

It may also output a C file which contains additional C functions to be linked into the program, together with a C header that gets included into the C code to which the Haskell module will be compiled (when compiled via C) and into the C file. These two files are created when the #def construct is used.

Actually hs2c does not output the Haskell file directly. It creates a C program that includes the headers, gets automatically compiled and run. That program outputs the Haskell code.

In the following, “Haskell file” is the main output (usually a .hs file), “compiled Haskell file” is the Haskell file after ghc has compiled it to C (i.e. a .hc file), “C program” is the program that outputs the Haskell file, “C file” is the optionally generated C file, and “C header” is its header file.

9.2.1. Command line syntax

glue-hsc takes input files as arguments, and flags that modify its behavior:

-t FILE or --template=FILE

The template file (see below).

--cc=PROG

The C compiler to use (default: ghc)

--ld=PROG

The linker to use (default: gcc).

--cflag=FLAG

An extra flag to pass to the C compiler.

--lflag=FLAG

An extra flag to pass to the linker.

--help

Display a summary of the available flags.

The input file should end with .hsc. Output files get names with the .hsc suffix replaced:

.hsHaskell file
_hsc.hC header
_hsc.cC file

The C program is compiled using the Haskell compiler. This provides the include path to HsFFI.h which is automatically included into the C program.

9.2.2. Input syntax

All special processing is triggered by the # character. To output a literal #, write it twice: ##.

Otherwise # is followed by optional spaces and tabs, an alphanumeric key that describes the kind of processing, and its arguments. Arguments look like C expressions and extend up to the nearest unmatched ), ], or }, or to the end of line outside any () [] {} '' "" /* */. Any character may be preceded by a backslash and will not be treated specially.

Meanings of specific keys:

#include <file.h>, #include "file.h"

The specified file gets included into the C program, the compiled Haskell file, and the C header. <HsFFI.h> is included automatically.

#define name, #define name value

Similar to #include. Note that #includes and #defines may be put in the same file twice so they should not assume otherwise.

#option opt

The specified Haskell compiler command-line option is placed in the {-# OPTIONS #-} pragma at the top of the Haskell file (see Section 3.14.6). This is needed because glue-hsc emits its own OPTIONS pragma, and only one such pragma is interpreted by GHC.

#def C_definition

The definition (of a function, variable, struct or typedef) is written to the C file, and its prototype or extern declaration to the C header. Inline functions are handled correctly. struct definitions and typedefs are written to the C program too. The inline, struct or typedef keyword must come just after def.

#if condition, #ifdef name, #ifndef name, #elif condition, #else, #endif

Conditional compilation directives are passed unmodified to the C program, C file, and C header. Putting them in the C program means that appropriate parts of the Haskell file will be skipped.

#const C_expression

The expression must be convertible to long or unsigned long. Its value (literal or negated literal) will be output.

#const_str C_expression

The expression must be convertible to const char pointer. Its value (string literal) will be output.

#type C_type

A Haskell equivalent of the C numeric type will be output. It will be one of {Int,Word}{8,16,32,64}, Float, Double, LDouble.

#peek struct_type, field

A function that peeks a field of a C struct will be output. It will have the type Storable b => Ptr a -> IO b. The intention is that #peek and #poke can be used for implementing the operations of class Storable for a given C struct (see Section 4.25 in Haskell Libraries).

#poke struct_type, field

Similarly for poke. It will have the type Storable b => Ptr a -> b -> IO ().

#ptr struct_type, field

Makes a pointer to a field struct. It will have the type Ptr a -> Ptr b.

9.2.3. Custom constructs

#const, #type, #peek, #poke and #ptr are not hardwired into the hs2c, but are defined in a C template that is included in the C program: template-hsc.h. Custom constructs and templates can be used too. Any #-construct with unknown key is expected to be handled by a C template.

A C template should define a macro or function with name prefixed by hsc_ that handles the construct by emitting the expansion to stdout. See template-hsc.h for examples.