
While working on zesci I needed an easier and more sustainable way of using raylib. So I started making a binding generator that would spit out Zig binding definitions that could be easily updated when new commits are made to the raylib repository and breaking changes emerge.
Also I wanted them to be zig idiomatic in the sense that for example enum values can be passed with literals, int and float types are what you expect them to be in a typical zig api or when a pointer is involved in an API function it is clear to what it points.
Although Zig is able to import .h files and call C functions directly there are still some downsides. One is that whenever you work with a pointer you have to deal with [*c]T
. This is suboptimal as you don't know if its a single or multi item pointer and if it can be NULL. The other thing is that the IDE (in my case VSCode) cannot provide adequate tooltips and auto completion for imported C-header files.
Then there was also the problem when it comes to building with emscripten and calling functions with struct parameters. When the target platform is wasm32 only primitive types or pointers can be passed and returned. When you try to call those functions you get a weird 'index out of bounds' error.
So I needed a way to generate zig functions that call the raylib API but using Zig type safety and also wrap everything that is bigger than usize in a pointer.
While working on a script for parsing raylib.h
I Found out that the raylib repository already contains a tool called raylib_parser which can generate meta information for the raylib API (structs, enums, functions even constant values) in json.
This helped creating the bindings a lot. I even managed to generate bindings for raymath.h
, rlgl.h
, raygui.h
and physac.h
I use a 3 step workflow to generate a final raylib.zig
file that contains all definitions needed to work as a single import:
- Generate meta jsons (
raylib.json
,raygui.json
,raymath.json
,physac.json
) with raylib_parser - Convert them to zigyfied versions as intermediate step. Resulting in a binding.json that contains all structs, enums, functions and constants. Each definition can be modified by setting
custom=true
- Generate
raylib.zig
(andmarshal.h
+marshal.c
) from bindings.json and inject files
Here are some examples from raylib.com/examples.html recreated in Zig
Comments