Skip to content

Consider supporting closures/lambdas, not just function pointers #114

@dtolnay

Description

@dtolnay

Currently if we have:

mod ffi {
    extern "C++" {
        fn f(callback: fn());
    }
}

then Rust can call it as:

ffi::f(|| {
    do_something();
});

but not with any closure captures:

// not allowed

let x = /* ... */;
ffi::f(|| {
    do_something(x);
});

This gets very complicated from a lifetimes perspective, not to mention a FnOnce vs Fn perspective, so there is a good chance that we don't end up supporting this. But it is worth exploring.

The workaround for now is to pass context through manually via an opaque Rust type.

mod ffi {
    extern "Rust" {
        type CallbackContext;
    }

    extern "C++" {
        fn f(
            callback: fn(ctx: Box<CallbackContext>),
            ctx: Box<CallbackContext>,
        );
    }
}

let x = /* ... */;
ffi::f(
    |ctx| {
        do_something(ctx);
    },
    Box::new(x),
);

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions