{{#title Async functions — Rust ♡ C++}} # Async functions Direct FFI of async functions is absolutely in scope for CXX (on C++20 and up) but is not implemented yet in the current release. We are aiming for an implementation that is as easy as: ```rust,noplayground #[cxx::bridge] mod ffi { unsafe extern "C++" { async fn doThing(arg: Arg) -> Ret; } } ``` ```cpp,hidelines rust::Future doThing(Arg arg) { auto v1 = co_await f(); auto v2 = co_await g(arg); co_return v1 + v2; } ``` ## Workaround For now the recommended approach is to handle the return codepath over a oneshot channel (such as [`futures::channel::oneshot`]) represented in an opaque Rust type on the FFI. [`futures::channel::oneshot`]: https://docs.rs/futures/0.3.8/futures/channel/oneshot/index.html ```rust,noplayground // bridge.rs use futures::channel::oneshot; #[cxx::bridge] mod ffi { extern "Rust" { type DoThingContext; } unsafe extern "C++" { include!("path/to/bridge_shim.h"); fn shim_doThing( arg: Arg, done: fn(Box, ret: Ret), ctx: Box, ); } } struct DoThingContext(oneshot::Sender); pub async fn do_thing(arg: Arg) -> Ret { let (tx, rx) = oneshot::channel(); let context = Box::new(DoThingContext(tx)); ffi::shim_doThing( arg, |context, ret| { let _ = context.0.send(ret); }, context, ); rx.await.unwrap() } ``` ```cpp // bridge_shim.cc #include "path/to/bridge.rs.h" #include "rust/cxx.h" void shim_doThing( Arg arg, rust::Fn ctx, Ret ret)> done, rust::Box ctx) noexcept { doThing(arg) .then([done, ctx(std::move(ctx))](auto &&res) mutable { (*done)(std::move(ctx), std::move(res)); }); } ```