[ocaml-ctypes] Variadic Functions

Jeremy Yallop yallop at gmail.com
Mon Sep 30 14:31:01 BST 2013


On 24 September 2013 12:43, Florian Pichlmeier
<florian.pichlmeier at mytum.de> wrote:
> Some of these functions are variadic functions, like this one
>
> //  Create new poller
> CZMQ_EXPORT zpoller_t *
>     zpoller_new (void *reader, ...);
>
> Is there a way with ctypes to emulate this signature?

The short answer, unfortunately, is "no".  This type of function is
rather tricky to wrap.  This isn't due to a limitation of ctypes; it's
because there isn't a way to write wrappers for variadic functions in
standard C [0, 1]

Ideally the C library interface should provide a more wrappable
interface in addition to the variadic function, e.g.

    zpoller_t *zpoller_new_vec(void **readers);    /* argument is a
null-terminated array of pointers */

or

    zpoller_t *zpoller_new_vec(void **readers, size_t nreaders);

It might be worth sending a pull request to the czmq maintainers to
modify the interface.

If you're not too concerned by portability you can use the fact that
some C implementations (e.g. GCC on Linux) have the same calling
convention for variadic and regular functions.  Here ctypes offers an
advantage over handwritten bindings: since C types are exposed as
OCaml values you can construct a signature dynamically according to
the number of arguments you want to pass to  the function.  For
example, you might call the function using any of the signatures

    ptr void @-> returning (ptr (zpoller_t))

    ptr void @-> ptr void @-> returning (ptr (zpoller_t))

    ptr void @-> ptr void @-> ptr void @-> returning (ptr (zpoller_t))

and so on.  In fact, it ought to be possible (but probably not easy)
to write a function which accepts a list of pointers, constructs a
suitable signature for zpoller_new and calls the function.

Jeremy.

[0] http://c-faq.com/varargs/handoff.html
[1] http://c-faq.com/varargs/invvarargs.html


More information about the Ctypes mailing list