Crate async_ffi[−][src]
FFI-compatible futures
In case of an async program with some async plugins, Future
s need to cross the FFI boundary.
But Rust currently doesn’t provide stable ABI nor stable layout of related structs like
dyn Future
and Waker
.
With this crate, we can easily wrap async blocks or async functions to make this happen.
FfiFuture<T>
provides the same function as Box<dyn Future<Output = T> + Send>
but FFI-compatible (repr(C)
).
Any future implementing Send
can be converted to FfiFuture<T>
by calling into_ffi
on it.
FfiFuture<T>
also implements Future<Output = T> + Send
. You can simply await
a FfiFuture<T>
like a normal Future
to get the output.
There is also a non-Send
version LocalFfiFuture<T>
working like
Box<dyn Future<Output = T>>
, which can be used for local future or single-threaded targets.
It is ABI-compatible to FfiFuture<T>
, but it’s your duty to guarantee that non-Send
types
never cross thread boundary.
Example
Provide some async functions in library: (plugin side)
// Compile with `crate-type = ["cdylib"]`. use async_ffi::{FfiFuture, FutureExt}; #[no_mangle] pub extern "C" fn work(arg: u32) -> FfiFuture<u32> { async move { let ret = do_some_io(arg).await; do_some_sleep(42).await; ret } .into_ffi() }
Execute async functions from external library: (host or executor side)
use async_ffi::{FfiFuture, FutureExt}; // #[link(name = "myplugin...")] extern "C" { #[no_mangle] fn work(arg: u32) -> FfiFuture<u32>; } async fn run_work(arg: u32) -> u32 { unsafe { work(arg).await } }
Structs
FfiFuture | The FFI compatible future type with |
LocalFfiFuture | The FFI compatible future type without |
Constants
ABI_VERSION | The ABI version of |
Traits
FutureExt | Helper trait to provide conversion from |