getditto/safer_ffi

Feature Request: Generate rust fn and struct declarations instead of C headers

coderedart opened this issue · 1 comments

My use case is pretty simple. I need to do rust <-> rust FFI for webassembly.

Basically, i want my app to be "scriptable" using wasm plugins. So, i would provide a bunch of functions (like drawing) from the host. When the guest plugin is loaded, it will be linked with these host functions as "imports". Then, the guest can call the host functions to draw stuff.

So, the host will have code like this:

// host.rs
struct Point {
	x: f32,
	y: f32
}

impl Point {
	/// Draw a line from self -> to
	pub fn draw_line(&self,  to: &Point) {
		// ... host side implementation using opengl or something.
	}
} 

Then, there will be a "guest_imports.rs" crate which will just include the FFI declarations necessary. Basically, bindings generated from C headers.

// generated from host.rs
struct Point {
	x: f32,
	y: f32,
}
// will be provided (linked) as imports by host at load time.
extern "C" {
	pub fn point_draw_line(this: * const Point, to: * const Point);
}
impl Point {
	/// automatically reconstruct the safe API on the guest side using the FFI bindings generated from the host
	pub fn draw_line(&self, to: &Point) {
		unsafe { point_draw_line(self as * const Point, to as * const Point) }
	}
}

Now, a guest plugin can simply depend on the above crate, with almost the same API (except with dynamically lined unsafe bindings under the hood).

Right now, trying to write rust <-> rust FFI is a horrible experience.

  1. Write the host functionality.
  2. use safer_ffi to generate the extern FFI fn declarations or do it manually.
    1. If you used safer_ffi, now you need to use bindgen to convert c headers to rust.
  3. Then, reconstruct the safe API using the FFI fns. copy paste the docs too :(

This leads to a lot of duplication and manual maintenance. For some reason, its more work to do rust <-> rust FFI than rust <-> C/Cpp FFI.

But, i was wondering if it is possible for safer_ffi to instead directly generate the rust ffi declarations (and even reconstruct the safe API using the declarations) automatically and skip the intermediary c language completely.

Yes, this is indeed a desired goal of this library, hopefully implemented this year (cannot promise a shorter timeframe since I don't have that much time to dedicate to this yet). For what is worth, you may be able to give ::stabby a try: it has similar design ideas to safer-ffi, but focuses on Rust-to-Rust FFI 🙂