[−][src]Crate safer_ffi
The User Guide
The recommended way to learn about ::safer_ffi
is through the user guide:
Prerequisites
Minimum Supported Rust Version: 1.43.0
Quickstart
Cargo.toml
Edit your Cargo.toml
like so:
[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"]
- Where
"*"
ought to be replaced by the last released version, which you can find by runningcargo search safer-ffi
.
src/lib.rs
use ::safer_ffi::prelude::*; /// A `struct` usable from both Rust and C #[derive_ReprC] #[repr(C)] #[derive(Debug, Clone, Copy)] pub struct Point { x: f64, y: f64, } /* Export a Rust function to the C world. */ /// Returns the middle point of `[a, b]`. #[ffi_export] 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. #[ffi_export] fn print_point (point: &Point) { println!("{:?}", point); } /// The following test function is necessary for the header generation. #[::safer_ffi::cfg_headers] #[test] fn generate_headers () -> ::std::io::Result<()> { ::safer_ffi::headers::builder() .to_file("rust_points.h")? .generate() }
Compilation & header generation
# Compile the C library (in `target/{debug,release}/libcrate_name.ext`)
cargo build # --release
# Generate the C header
cargo test --features c-headers -- generate_headers
Generated C header
/*! \file */
/*******************************************
* *
* File auto-generated by `::safer_ffi`. *
* *
* Do not manually edit this file. *
* *
*******************************************/
#ifndef __RUST_CRATE_NAME__
#define __RUST_CRATE_NAME__
#ifdef __cplusplus
extern "C" {
#endif
/** \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]`.
*/
Point_t mid_point (
Point_t const * a,
Point_t const * b);
/** \brief
* Pretty-prints a point using Rust's formatting logic.
*/
void print_point (
Point_t const * point);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* __RUST_CRATE_NAME__ */
Testing it
main.c
#include <stdlib.h>
#include "rust_points.h"
int main (int argc, char const * const argv[])
{
Point_t a = { .x = 84, .y = 45 };
Point_t b = { .x = 0, .y = 39 };
Point_t m = mid_point(&a, &b);
print_point(&m);
return EXIT_SUCCESS;
}
Compilation command
cc main.c -o main -L target/debug -l crate_name
# Now feel free to run the compiled binary
./main
which outputs:
Point { x: 42.0, y: 42.0 }
🚀🚀
Re-exports
pub use tuple::*; |
Modules
boxed | feature="alloc"
|
char_p |
|
closure | Closures with a |
headers | feature="headers" C headers generation. |
layout | Trait abstractions describing the semantics of "being |
prelude | |
ptr | Wrappers around |
slice | Logic common to all fat pointers. |
string |
|
tuple | Tuple types with a guaranteed |
vec | feature="alloc" |
Macros
CType | Safely implement |
NULL | |
ReprC | Safely implement |
c | feature="proc_macros" Creates a compile-time checked |
c_vec |
Structs
String | feature="alloc" Same as |
Vec | feature="alloc" Same as |
Attribute Macros
cfg_headers | |
derive_ReprC | feature="proc_macros" Safely implement |
ffi_export | Export a function to be callable by C. |