[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