Crate seesaw

Crate seesaw 

Source
Expand description

Generate traits from C header files.

When rewriting a C libary in Rust, you often want to preserve the original C header files.

This is possible using this crate in conjuction with bindgen.

Take the following C header.

typedef struct yakshaver yakshaver;

/** create a yakshaver */
yakshaver *create(void);
/** destroy a yakshaver */
void destroy(yakshaver *);
/** get number of yaks shaved */
unsigned int yaks_shaved(const yakshaver *);
/** shave some yaks */
int shave(yakshaver *);

In your build.rs script:

  1. Use bindgen to generate equivalent Rust blocks.
  2. Use seesaw to generate a trait from those bindings.
// build.rs
let bindings = bindgen::builder().header("yakshaver.h").generate()?;
seesaw::seesaw("Yakshaver", &bindings, "generated/seesaw.rs")?;
bindings.write_to_file("generated/bindgen.rs")?;

The generated file will look like this:

/* this file is @generated by seesaw 0.1.6 */

#[allow(unused)]
pub trait Yakshaver {
    #[doc = " create a yakshaver"]
    unsafe extern "C" fn create() -> *mut yakshaver;
    #[doc = " destroy a yakshaver"]
    unsafe extern "C" fn destroy(arg1: *mut yakshaver);
    #[doc = " get number of yaks shaved"]
    unsafe extern "C" fn yaks_shaved(arg1: *const yakshaver) -> ::std::os::raw::c_uint;
    #[doc = " shave some yaks"]
    unsafe extern "C" fn shave(arg1: *mut yakshaver) -> ::std::os::raw::c_int;
}

And you can export the same ABI as the C library using no_mangle, which simply adds #[no_mangle] to each of the functions.

#[seesaw::no_mangle]
impl YakShaver for () { .. }

Structs§

Trait
A specification of a trait generated from a C header.
TraitSet
A combination of multiple Trait definitions.

Enums§

Destination
Utility struct for where bindings are written.

Functions§

seesaw
Generate a trait from a C header that’s passed through bindgen.

Attribute Macros§

no_mangle
Accept an impl block, and add a #[no_mangle] attribute to each of the member