Skip to content

C‐wrapper & Async

Thomas Fossati edited this page Oct 11, 2024 · 4 revisions

Compiling

As part of PR#17, I have modified veraison_get_verification_api() to make it async.

When compiling, I get a bunch of "not FFI-safe" warnings:

cargo build

[...]

warning: `extern` fn uses type `impl Future<Output = VeraisonResult>`, which is not FFI-safe
   --> c-wrapper/src/lib.rs:305:1
    |
305 | / pub async unsafe extern "C" fn open_challenge_response_session(
306 | |     new_session_url: *const libc::c_char,
307 | |     nonce_size: libc::size_t,
308 | |     nonce: *const u8,
309 | |     out_session: *mut *mut ChallengeResponseSession,
310 | | ) -> VeraisonResult {
    | |___________________^ not FFI-safe
    |
    = note: opaque types have no C equivalent
    = note: `#[warn(improper_ctypes_definitions)]` on by default

warning: `extern` fn uses type `impl Future<Output = VeraisonResult>`, which is not FFI-safe
   --> c-wrapper/src/lib.rs:439:1
    |
439 | / pub async unsafe extern "C" fn challenge_response(
440 | |     session: *mut ChallengeResponseSession,
441 | |     evidence_size: libc::size_t,
442 | |     evidence: *const u8,
443 | |     media_type: *const libc::c_char,
444 | | ) -> VeraisonResult {
    | |___________________^ not FFI-safe
    |
    = note: opaque types have no C equivalent

warning: `extern` fn uses type `impl Future<Output = VeraisonResult>`, which is not FFI-safe
   --> c-wrapper/src/lib.rs:538:1
    |
538 | / pub async unsafe extern "C" fn veraison_get_verification_api(
539 | |     veraison_service_base_url: *const libc::c_char,
540 | |     out_api: *mut *mut VeraisonVerificationApi,
541 | | ) -> VeraisonResult {
    | |___________________^ not FFI-safe
    |
    = note: opaque types have no C equivalent

which make sense because it's returning a future, which is something that likely needs some coordination between the two sides (Rust & C) to be produced/consumed in any meaningful way. It's not that you can throw it over the fence and expect the other end to make sense of it automagically.

Executing

When executing the example program - surprise! - I get SIGSEGV exactly at the boundary that the compiler flagged as "not FFI-safe":

$ gdb -ex run ./challenge-response

[...]

Program received signal SIGSEGV, Segmentation fault.
veraison_apiclient_ffi::veraison_get_verification_api (veraison_service_base_url=0xaaaaab3d5008, out_api=0xffffffffd9a8) at c-wrapper/src/lib.rs:541
541     ) -> VeraisonResult {
(gdb) list
536     /// not a null pointer.
537     #[no_mangle]
538     pub async unsafe extern "C" fn veraison_get_verification_api(
539         veraison_service_base_url: *const libc::c_char,
540         out_api: *mut *mut VeraisonVerificationApi,
541     ) -> VeraisonResult {
542         // We have to trust the caller's char* ptr.
543         let url_str: &str = {
544             let url_cstr = CStr::from_ptr(veraison_service_base_url);
545             url_cstr.to_str().unwrap()
(gdb) 

A Rust Noob is Puzzled

Are async and C bindings compatible?

Clone this wiki locally