Query C for struct layout

### What's this?

A new module, `Cstubs_structs`, that supports retrieving the layout of structs and unions from C declarations.

### What problem does it solve?

The [current structure description API][structure-api] computes the layout of the structs and unions you describe in your program.  This works well in simple cases if you're careful, but there's no check that what you write matches the declared type, and some cases are tricky to handle.  For example, there's currently no clear solution for when

* The C library uses compiler directives such as [#pragma pack][pragma-pack] to change the field layout algorithm
* The layout of a struct differs between versions of a library
* The set of fields in a struct changes according to platform

### How does this change solve the problem?

The new module generates C code that is compiled against the header to retrieve the struct layout information from the C compiler, guaranteeing that the layout of structs used in your OCaml/ctypes program matches the layout in the C library you're binding.

### How do I use it?

The interface is very similar to the existing structure description API, and in most cases it should be easy to switch.  Let's consider an example.  Here's a simple C struct declaration:

```C
struct cell
{
  int payload;
  struct cell *next;
};
```

You can describe this struct using the existing API as follows:

```ocaml
let cell    = structure "cell"
let payload = field cell int "payload"
let next    = field cell (ptr cell) "next"
let ()      = seal cell
```

With the `Cstubs_structs` module in this pull request you put the declaration inside a functor:

```ocaml
module Bindings(S : Cstubs_structs.STRUCT) =
struct
  open S
  let cell    = structure "cell"
  let payload = field cell int "payload"
  let next    = field cell (ptr cell) "next"
  let ()      = seal cell
end
```

and then pass the functor to generate a C program:

```ocaml
Cstubs_structs.write_c formatter (module Bindings)
```

The C program then an ML module which you can link in to your program:

```ocaml
include Bindings(Generated_module) 
```

### Isn't the build process rather complex?

Perhaps, but each step has a clear rationale.  Generating C is the best way to retrieve information from library headers.  Having the C program then generate an ML program makes it possible to inline the retrieved layout information into your program.  Using a functor to link the generator and the generated code together makes it possible to give strong guarantees about typing.