You get the added benefit of being able to easily consume C libraries without much fuss. The fuss is in navigating the C APIs of decades old libraries that we all still depend on every day.
You get the added benefit of being able to easily consume C libraries without much fuss. The fuss is in navigating the C APIs of decades old libraries that we all still depend on every day.
They wouldn't be using Zig otherwise. :)
In Zig, you can just import a C header. And as long as you have configured the source location in your `build.zig` file, off you go. Zig automatically generates bindings for you. Import the header and start coding.
This is all thanks to Zig's `translate-c` utility that is used under the hood.
Rust by contrast has a lot more steps required, including hand writing the function bindings.
In general, the expectation is that you will use bindgen [0].
It's a very easy process:
1. Create a `build.rs` file in your Rust project, which defines pre-build actions. Use it to call bindgen on whatever headers you want to import, and optionally to define library linkage. This file is very simple and mainly boilerplate. [1]
2. Import your bindgen-generated Rust module... just use it. [2]
You can also skip step 1: bindgen is also a CLI tool, so if your C target is stable, you can just run bindgen once to generate the Rust interface module and move that right into your crate.
[0]: https://rust-lang.github.io/rust-bindgen/
[1]: https://rust-lang.github.io/rust-bindgen/tutorial-3.html
[2]: https://github.com/Charles-Schleich/Rust-Bindgen-Example/blo...
Yes, but it's mostly cultural.
Rust folks have a nasty habit of trying to "Rust-ify" bindings. And then proceed to only do the easy 80% of the job. So now you wind up debugging an incomplete set of bindings with strange abstractions and the wrapped library.
Zig folks suck in the header file and deal with the library as-is. That's less pretty, but it's also less complicated.