Skip to main content

Function

Struct Function 

Source
pub struct Function { /* private fields */ }
Expand description

An callable FFI function.

Function can be used to call FFI functions in cases where the signature is not known at compile-time.

§Example

use fiffi::function::{Function, arg, ret};
use fiffi::types::Type;

extern "C" fn double(value: i32) -> i32 {
    value * 2
}

let fn_ptr = fiffi::fn_ptrize!(double);
let function = Function::new(fn_ptr, &[Type::I32], Some(&Type::I32));

let input = 21i32;
let mut output = 0i32;

// SAFETY: The function signature used to construct `function` matches `double`.
unsafe {
    function.call([arg(&input)], ret(&mut output));
}

assert_eq!(output, 42);

Implementations§

Source§

impl Function

Source

pub fn new<'args, I>( fn_ptr: FnPtr, argument_types: I, return_type: Option<&Type>, ) -> Self
where I: IntoIterator<Item = &'args Type>,

Create a Function using the target’s default ABI.

§Warning

libffi stores the number of arguments in a C unsigned int. If more than c_uint::MAX argument types are provided, only the first c_uint::MAX are retained in the prepared function signature.

Source

pub fn variadic<'fixed_args, 'variadic_args, I1, I2>( fn_ptr: FnPtr, fixed_argument_types: I1, variadic_argument_types: I2, return_type: Option<&Type>, ) -> Self
where I1: IntoIterator<Item = &'fixed_args Type>, I2: IntoIterator<Item = &'variadic_args VariadicType>,

Create a variadic Function using the target’s default ABI.

fixed_argument_types must describe the fixed parameters, and variadic_argument_types must describe the variadic arguments supplied for a call.

§Warning

libffi stores the number of arguments in a C unsigned int. If more than c_uint::MAX argument types are provided, only the first c_uint::MAX are retained in the prepared function signature.

Fixed arguments are retained before variadic arguments if the signature is truncated.

§Example
use std::ffi::c_char;

use fiffi::function::{Function, arg, ret};
use fiffi::types::{Type, VariadicType};

#[cfg_attr(target_env = "msvc", link(name = "legacy_stdio_definitions"))]
unsafe extern "C" {
    pub unsafe fn snprintf(s: *mut c_char, n: usize, format: *const c_char, ...) -> i32;
}

let function = Function::variadic(
    fiffi::fn_ptrize!(snprintf),
    // Fixed arguments
    //Output buffer  Buffer size  Format string
    &[Type::Pointer, Type::Usize, Type::Pointer],
    // Variadic arguments
    &[VariadicType::I32],
    Some(&Type::I32),
);

let format = c"Num: %d";
let num = 1337i32;
let expected = c"Num: 1337".to_bytes_with_nul();

let mut output_buffer = [0u8; 128];
let mut return_value = 0i32;

// SAFETY: `function` was built with a valid `snprintf` function pointer and the correct
// function signature for `snprintf` with a single `i32` variadic argument.
unsafe {
    function.call(
        [
            arg(&output_buffer.as_mut_ptr()),
            arg(&output_buffer.len()),
            arg(&format),
            arg(&num),
        ],
        ret(&mut return_value),
    );
}

// `snprintf`'s return value return the written length without the final NULL byte.
assert_eq!(return_value as usize, expected.len() - 1);
assert_eq!(expected, &output_buffer[0..expected.len()]);
Source

pub fn with_abi<'args, I>( fn_ptr: FnPtr, argument_types: I, return_type: Option<&Type>, abi: Abi, ) -> Self
where I: IntoIterator<Item = &'args Type>,

Creates a Function using the provided Abi.

§Warning

libffi stores the number of arguments in a C unsigned int. If more than c_uint::MAX argument types are provided, only the first c_uint::MAX are retained in the prepared function signature.

Source

pub fn variadic_with_abi<'fixed_args, 'variadic_args, I1, I2>( fn_ptr: FnPtr, fixed_argument_types: I1, variadic_argument_types: I2, return_type: Option<&Type>, abi: Abi, ) -> Self
where I1: IntoIterator<Item = &'fixed_args Type>, I2: IntoIterator<Item = &'variadic_args VariadicType>,

Creates a variadic Function using the provided Abi.

fixed_argument_types must describe the fixed parameters, and variadic_argument_types must describe the variadic arguments supplied for a call.

§Warning

libffi stores the number of arguments in a C unsigned int. If more than c_uint::MAX argument types are provided, only the first c_uint::MAX are retained in the prepared function signature.

Fixed arguments are retained before variadic arguments if the signature is truncated.

Source

pub fn builder() -> FunctionBuilder<FnPtrNotSet>

Create a FunctionBuilder used to build a Function.

§Example
use fiffi::function::Function;
use fiffi::types::Type;

extern "C" fn add(a: i32, b: i64) -> i64 {
    i64::from(a) + b
}

let function = Function::builder()
    .arg(Type::I32)
    .arg(Type::I64)
    .ret(Some(Type::I64))
    .fn_ptr(fiffi::fn_ptrize!(add))
    .build();
Source

pub fn variadic_builder() -> VariadicFunctionBuilder<FnPtrNotSet>

Create a VariadicFunctionBuilder used to build a variadic Function.

Source

pub unsafe fn call<'arg, I>(&self, args: I, ret: Ret<'_>)
where I: IntoIterator<Item = Arg<'arg>>,

Calls the wrapped function pointer through libffi.

§Safety
  • The wrapped FnPtr must be valid to call with this function’s ABI and signature.
  • Every Arg in args must point to an initialized value matching the corresponding Type the function expects and remain alive for the duration of the call.
  • All arguments expected by the called function must be provided.
  • ret must be valid to write the return type to, unless the function was created with no return type.
  • Calling the target function must not violate Rust aliasing rules for any referenced memory.

If more than c_uint::MAX argument types were provided during construction, libffi will use the truncated signature and may not read every argument pointer provided in args.

§Example
use fiffi::function::{Function, arg, ret};
use fiffi::types::Type;

extern "C" fn add_one(value: i32) -> i32 {
    value + 1
}

let function = Function::new(fiffi::fn_ptrize!(add_one), &[Type::I32], Some(&Type::I32));
let input = 41i32;
let mut output = 0i32;

// SAFETY: The function pointer, argument type, return type, and storage match `add_one`.
unsafe {
    function.call([arg(&input)], ret(&mut output));
}

assert_eq!(output, 42);
Source

pub fn argument_layouts(&self) -> Vec<FfiTypeLayout>

Returns the memory layout of this Function’s arguments.

§Example
use fiffi::function::Function;
use fiffi::types::Type;

extern "C" fn identity(value: i32) -> i32 {
    value
}

let function = Function::new(fiffi::fn_ptrize!(identity), &[Type::I32], Some(&Type::I32));

assert_eq!(function.argument_layouts(), vec![Type::I32.layout()]);
Source

pub fn return_layout(&self) -> FfiTypeLayout

Returns the memory layout of this Function’s return value.

§Example
use fiffi::function::Function;
use fiffi::types::Type;

extern "C" fn identity(value: i32) -> i32 {
    value
}

let function = Function::new(fiffi::fn_ptrize!(identity), &[Type::I32], Some(&Type::I32));

assert_eq!(function.return_layout(), Type::I32.layout());

Trait Implementations§

Source§

impl Clone for Function

Source§

fn clone(&self) -> Function

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Function

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Send for Function

Source§

impl Sync for Function

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.