safer_ffi
?safer_ffi
is a framework that helps you write foreign function interfaces (FFI) without polluting your Rust code with unsafe { ... }
code blocks while making functions far easier to read and maintain.
Minimum Supported Rust Version: 1.43.0
Cargo.toml
Edit your Cargo.toml
like so:
```toml [package] name = "crate_name" version = "0.1.0" edition = "2018"
[lib] crate-type = ["staticlib"]
[dependencies] safer-ffi = { version = "*", features = ["proc_macros"] }
[features] c-headers = ["safer-ffi/headers"] ```
"*"
ought to be replaced by the last released version, which you
can find by running cargo search safer-ffi
.src/lib.rs
```rust,ignore use ::safer_ffi::prelude::*;
/// A struct
usable from both Rust and C
pub struct Point { x: f64, y: f64, }
/* Export a Rust function to the C world. */
/// Returns the middle point of [a, b]
.
fn mid_point ( a: &Point, b: &Point, ) -> Point { Point { x: (a.x + b.x) / 2., y: (a.y + b.y) / 2., } }
/// Pretty-prints a point using Rust's formatting logic.
fn print_point (point: &Point) { println!("{:?}", point); }
/// The following test function is necessary for the header generation.
fn generateheaders () -> ::std::io::Result<()> { ::saferffi::headers::builder() .tofile("rustpoints.h")? .generate() } ```
```bash
target/{debug,release}/libcrate_name.ext
)cargo build # --release
cargo test --features c-headers -- generate_headers ```
Generated C header
``C
/*! \file */
/*******************************************
* *
* File auto-generated by
::safer_ffi`. *
* *
* Do not manually edit this file. *
* *
*************/
extern "C" {
/** \brief
* A struct
usable from both Rust and C
*/
typedef struct {
double x;
double y;
} Point_t;
/** \brief
* Returns the middle point of [a, b]
.
*/
Pointt midpoint (
Pointt const * a,
Pointt const * b);
/** \brief * Pretty-prints a point using Rust's formatting logic. */ void printpoint ( Pointt const * point);
} /* extern "C" */
```
main.c
```C
int main (int argc, char const * const argv[]) { Pointt a = { .x = 84, .y = 45 }; Pointt b = { .x = 0, .y = 39 }; Pointt m = midpoint(&a, &b); printpoint(&m); return EXITSUCCESS; } ```
```bash cc main.c -o main -L target/debug -l crate_name
./main ```
which outputs:
text
Point { x: 42.0, y: 42.0 }
🚀🚀