[ocaml-ctypes] Finalising data

Jeremy Yallop yallop at gmail.com
Wed May 28 07:53:42 BST 2014


On 28 May 2014 11:47, Jeremy Yallop <yallop at gmail.com> wrote:
> On 27 May 2014 01:21, Florian Pichlmeier <florian.pichlmeier at mytum.de> wrote:
>> i changed the representation of zframe_t
>>
>> type frame
>> type t = frame structure ptr
>> let zframe_t : frame structure typ = structure "_zframe_t"
>
> Looks good!
>
>>> Although 'zframe_t' is incomplete, 'ptr zframe_t' (i.e. zframe_t*) is
>>> complete, so pointer arithmetic (with +@ etc.) should work as you
>>> expect.
>>
>> I tried this approach with pointer arithmetic (+@), but i still get
>> the Static.IncompleteType exception when i call the destroy function.
>>
>> let destroy (msg : t) =
>>   let stub = foreign "zframe_destroy" ((ptr zframe_t) @-> returning int) in
>>   stub (msg +@ 0)
>>
>> Another problem is, that the zframe_destroy function expects **zframe_t as input,
>> but with msg +@ 0 i only get *zframe_t. Does it suffice to declare the function
>> like i did above, or do i need another approach?
>
> Right: this is the source of the difficulty.  The argument to the C
> function is a pointer to pointer:
>
>    void zframe_destroy(frame_t **)
>
> and so the argument in the ctypes binding needs two 'ptr' applications:
>
>    let stub = foreign "zframe_destroy" (ptr (ptr zframe_t) @-> returning void)

By the way, the new stub generation facility in 0.3 catches the error
during compilation.

Here's your binding, moved inside a functor to make it available for
stub generation:

    $ cat czmq.ml
    open Ctypes
    type frame
    type t = frame structure ptr
    let zframe_t : frame structure typ = structure "_zframe_t"

    module Bindings(F : Cstubs.FOREIGN) =
    struct
      let zframe_destroy = F.foreign "zframe_destroy" (ptr zframe_t
@-> returning void)
    end

You also need a simple driver for generating C code from the bindings:

    $ cat generate.ml
    let () =
      Format.printf "#include <czmq.h>\n";
      Cstubs.write_c ~prefix:"czmq" Format.std_formatter (module Czmq.Bindings)

Now you can build the generator and run it to generate the C stubs:

    $ ocamlfind ocamlc -o gen -package ctypes.stubs -linkpkg czmq.ml generate.ml
    $ ./gen > czmq_stubs.c

Finally, compiling the generated stub results in a useful diagnostic
from the C compiler:

    $ ocamlc -c -I $(ocamlc -where)/.. czmq_stubs.c
    czmq_stubs.c: In function ‘czmq_1_zframe_destroy’:
    czmq_stubs.c:7:4: warning: passing argument 1 of ‘zframe_destroy’
from incompatible pointer type [enabled by default]
        zframe_destroy(x2);
        ^
    In file included from /usr/local/include/czmq.h:36:0,
             from czmq_stubs.c:1:
    /usr/local/include/zframe.h:39:5: note: expected ‘struct zframe_t
**’ but argument is of type ‘struct _zframe_t *’
        zframe_destroy (zframe_t **self_p);
        ^

Jeremy


More information about the Ctypes mailing list