ocamllabs/ocaml-ctypes — pull request #129 by yallop (2014-02-22 22:12:42+00:00)
Title: High-level stub generation interface

The [previous stub generation interface](#124) was based on low-level functions for generating individual C and ML function definitions. This change introduces a higher-level interface based around functors.

Using the new interface involves three steps.

### Step 1: write the bindings

First, write your `foreign` bindings inside a functor parameterized by the [FOREIGN signature][foreign-sig]. For example, you might bind `puts` and `sqrt` as follows:

```ocaml
module Bindings (F: FOREIGN) =
struct
let puts = F.foreign "puts" (string @-> returning int)
let sqrt = F.foreign "sqrt" (double @-> returning double)
end
```

### Step 2: generate stubs

Stubs come in two parts: a C component that translates between C and OCaml representations, and an OCaml component that links the C functions into your program.

You can generate both components by passing the `Bindings` functor to [`write_c`][write_c] and [`write_ml`][write_ml]:

```ocaml
Cstubs.write_c fmt ~prefix:"libfoo_" (module Bindings)
Cstubs.write_ml fmt ~prefix:"libfoo_" (module Bindings)
```

### Step 3: link the stubs

Finally, you can compile the generated code to produce an OCaml module, and link the module into your program by passing it to the `Bindings` functor that you wrote in Step 1:

```ocaml
module B = Bindings(Generated_bindings)

let () = B.puts "Hello, world";
```

[foreign-sig]: https://github.com/yallop/ocaml-ctypes/blob/stubs-with-linking/src/cstubs/cstubs.mli#L10-L14
[write_c]: https://github.com/yallop/ocaml-ctypes/blob/stubs-with-linking/src/cstubs/cstubs.mli#L18
[write_ml]: https://github.com/yallop/ocaml-ctypes/blob/stubs-with-linking/src/cstubs/cstubs.mli#L27
[external]: http://caml.inria.fr/pub/docs/manual-ocaml-4.00/manual033.html#toc142