Eigenstate: myrddin-dev mailing list

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

C Bindings Autogeneration.


I've put together some code to do C binding autogeneration using libclang.

    http://git.eigenstate.org/ori/mcbind.git

You can already use it to generate bindings, although at the moment it's
not especially discriminating, and will put all symbols in a header or
set of headers into one package, transitively. So, to use it:

    mcbind -p mypackage foo.h

This will generate two files:

    mypackage.myr
    mypackage-glue.c

The main issue that I'm going to have to sort out to make this more pleasant
to use is a way of not including everything transitively. For example, if
I generate a binding for stdio.h, I shouldn't duplicate the types for size_t
and friends from stddef.h, but instead refer to a stddef.h module. For
example:

    stdio.write:(fd : int, buf : void#, count : stddef.size_t -> stddef.ssize_t)

instead of the subtly different

    stdio.write : (fd : int, buf : void#, count : stdio.size_t -> stdio.ssize_t)

As far as the generated bindings, the functions currently map directly,
with wrappers generated to paper over any ABI incompatibilities. There's
currently no method of wrapping strings and slices from Myrddn to C and
back; I'm not sure how I'd want to do that either. Ideally, we should end
up mapping, for example, stdio.write to:

    stdio.write : (fd : int, buf : byte[:] -> ssize_t)

But I'm not sure how to handle that without some sort of manual intervention.

As far as the currently generated code, if foo.h contains;

    struct foo {
        int a;
    };

    int f(char *a, int b);
    
Then mypackage.myr will contain:

    pkg mypackage =
        type foo = struct
            a : int32
        ;;
        extern const f  : (a0 : int8#, a1 : int32 -> int32)
    ;;


And mypackage-glue.c will contain:

    #include <stdint.h>
    #include <stddef.h>
    #include <foo.h>

    int32_t  mypackage$f(int8_t (*a1), int32_t a2)
    {
            return f(a1, a2);
    }

If there was an ABI incompatibility, f_wrapped() would be generated to
paper over the issues.

-- 
    Ori Bernstein