pub struct Closure<'a> { /* private fields */ }
Expand description
Represents a closure callable from C.
A libffi closure captures a void*
(“userdata”) and passes it to a
callback when the code pointer (obtained via
code_ptr
) is invoked. Lifetype parameter 'a
ensures that the closure does not outlive the userdata.
Construct with Closure::new
and
Closure::new_mut
.
§Examples
In this example we turn a Rust lambda into a C function. We first
define function lambda_callback
, which will be called by libffi
when the closure is called. The callback function takes four
arguments: a CIF describing its arguments, a pointer for where to
store its result, a pointer to an array of pointers to its
arguments, and a userdata pointer. In this ase, the Rust closure
value lambda
is passed as userdata to lambda_callback
, which
then invokes it.
use std::mem;
use std::os::raw::c_void;
use deno_libffi::middle::*;
use deno_libffi::low;
unsafe extern "C" fn lambda_callback<F: Fn(u64, u64) -> u64>(
_cif: &low::ffi_cif,
result: &mut u64,
args: *const *const c_void,
userdata: &F)
{
let args = args as *const &u64;
let arg1 = **args.offset(0);
let arg2 = **args.offset(1);
*result = userdata(arg1, arg2);
}
let cif = Cif::new(vec![Type::u64(), Type::u64()].into_iter(),
Type::u64());
let lambda = |x: u64, y: u64| x + y;
let closure = Closure::new(cif, lambda_callback, &lambda);
let fun: &extern "C" fn(u64, u64) -> u64 = unsafe {
closure.instantiate_code_ptr()
};
assert_eq!(11, fun(5, 6));
assert_eq!(12, fun(5, 7));
Implementations§
Source§impl<'a> Closure<'a>
impl<'a> Closure<'a>
Sourcepub fn new<U, R>(cif: Cif, callback: Callback<U, R>, userdata: &'a U) -> Self
pub fn new<U, R>(cif: Cif, callback: Callback<U, R>, userdata: &'a U) -> Self
Creates a new closure with immutable userdata.
§Arguments
cif
— describes the calling convention and argument and result typescallback
— the function to call when the closure is invokeduserdata
— the pointer to pass tocallback
along with the arguments when the closure is called
§Result
The new closure.
Sourcepub fn new_mut<U, R>(
cif: Cif,
callback: CallbackMut<U, R>,
userdata: &'a mut U,
) -> Self
pub fn new_mut<U, R>( cif: Cif, callback: CallbackMut<U, R>, userdata: &'a mut U, ) -> Self
Creates a new closure with mutable userdata.
§Arguments
cif
— describes the calling convention and argument and result typescallback
— the function to call when the closure is invokeduserdata
— the pointer to pass tocallback
along with the arguments when the closure is called
§Result
The new closure.
Sourcepub fn code_ptr(&self) -> &unsafe extern "C" fn()
pub fn code_ptr(&self) -> &unsafe extern "C" fn()
Obtains the callable code pointer for a closure.
§Safety
The result needs to be transmuted to the correct type before it can be called. If the type is wrong then undefined behavior will result.
Sourcepub unsafe fn instantiate_code_ptr<T>(&self) -> &T
pub unsafe fn instantiate_code_ptr<T>(&self) -> &T
Transmutes the callable code pointer for a closure to a reference to any type. This is intended to be used to transmute it to its correct function type in order to call it.
§Safety
This method allows transmuting to a reference to any sized type, and cannot check whether the code pointer actually has that type. If the type is wrong then undefined behavior will result.