#![doc(html_root_url = "https://docs.rs/libffi-sys/1.0.0")]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]
#![allow(improper_ctypes)]
use std::mem::zeroed;
use std::os::raw::{c_char, c_long, c_uint, c_ulong, c_ushort, c_void};
pub type ffi_arg = c_ulong;
pub type ffi_sarg = c_long;
pub type ffi_abi = u32;
pub type ffi_status = u32;
pub type ffi_type_enum = u32;
pub const FFI_64_BIT_MAX: u64 = 9223372036854775807;
pub const FFI_CLOSURES: u32 = 1;
pub const FFI_GO_CLOSURES: u32 = 1;
pub const FFI_NATIVE_RAW_API: u32 = 0;
pub const FFI_SIZEOF_ARG: u32 = 8;
pub const FFI_SIZEOF_JAVA_RAW: u32 = 8;
pub const FFI_TRAMPOLINE_SIZE: u32 = 24;
pub const FFI_TYPE_COMPLEX: u32 = 15;
pub const FFI_TYPE_DOUBLE: u32 = 3;
pub const FFI_TYPE_FLOAT: u32 = 2;
pub const FFI_TYPE_INT: u32 = 1;
pub const FFI_TYPE_LAST: u32 = 15;
pub const FFI_TYPE_LONGDOUBLE: u32 = 4;
pub const FFI_TYPE_POINTER: u32 = 14;
pub const FFI_TYPE_SINT16: u32 = 8;
pub const FFI_TYPE_SINT32: u32 = 10;
pub const FFI_TYPE_SINT64: u32 = 12;
pub const FFI_TYPE_SINT8: u32 = 6;
pub const FFI_TYPE_STRUCT: u32 = 13;
pub const FFI_TYPE_UINT16: u32 = 7;
pub const FFI_TYPE_UINT32: u32 = 9;
pub const FFI_TYPE_UINT64: u32 = 11;
pub const FFI_TYPE_UINT8: u32 = 5;
pub const FFI_TYPE_VOID: u32 = 0;
pub const ffi_abi_FFI_FIRST_ABI: ffi_abi = 1;
pub const ffi_abi_FFI_UNIX64: ffi_abi = 2;
pub const ffi_abi_FFI_WIN64: ffi_abi = 3;
pub const ffi_abi_FFI_EFI64: ffi_abi = 3;
pub const ffi_abi_FFI_GNUW64: ffi_abi = 4;
pub const ffi_abi_FFI_LAST_ABI: ffi_abi = 5;
pub const ffi_abi_FFI_DEFAULT_ABI: ffi_abi = 2;
pub const ffi_status_FFI_OK: ffi_status = 0;
pub const ffi_status_FFI_BAD_TYPEDEF: ffi_status = 1;
pub const ffi_status_FFI_BAD_ABI: ffi_status = 2;
pub const ffi_type_enum_STRUCT: ffi_type_enum = 13;
pub const ffi_type_enum_COMPLEX: ffi_type_enum = 15;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ffi_type {
pub size: usize,
pub alignment: c_ushort,
pub type_: c_ushort,
pub elements: *mut *mut ffi_type,
}
impl Default for ffi_type {
fn default() -> Self {
unsafe { zeroed() }
}
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ffi_cif {
pub abi: ffi_abi,
pub nargs: c_uint,
pub arg_types: *mut *mut ffi_type,
pub rtype: *mut ffi_type,
pub bytes: c_uint,
pub flags: c_uint,
}
impl Default for ffi_cif {
fn default() -> Self {
unsafe { zeroed() }
}
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union ffi_raw {
pub sint: ffi_sarg,
pub uint: ffi_arg,
pub flt: f32,
pub data: [c_char; 8usize],
pub ptr: *mut c_void,
_bindgen_union_align: u64,
}
impl Default for ffi_raw {
fn default() -> Self {
unsafe { zeroed() }
}
}
pub type ffi_java_raw = ffi_raw;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ffi_closure {
pub tramp: [c_char; 24usize],
pub cif: *mut ffi_cif,
pub fun: Option<
unsafe extern "C" fn(
arg1: *mut ffi_cif,
arg2: *mut c_void,
arg3: *mut *mut c_void,
arg4: *mut c_void,
),
>,
pub user_data: *mut c_void,
}
impl Default for ffi_closure {
fn default() -> Self {
unsafe { zeroed() }
}
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ffi_raw_closure {
pub tramp: [c_char; 24usize],
pub cif: *mut ffi_cif,
pub translate_args: Option<
unsafe extern "C" fn(
arg1: *mut ffi_cif,
arg2: *mut c_void,
arg3: *mut *mut c_void,
arg4: *mut c_void,
),
>,
pub this_closure: *mut c_void,
pub fun: Option<
unsafe extern "C" fn(
arg1: *mut ffi_cif,
arg2: *mut c_void,
arg3: *mut ffi_raw,
arg4: *mut c_void,
),
>,
pub user_data: *mut c_void,
}
impl Default for ffi_raw_closure {
fn default() -> Self {
unsafe { zeroed() }
}
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ffi_java_raw_closure {
pub tramp: [c_char; 24usize],
pub cif: *mut ffi_cif,
pub translate_args: Option<
unsafe extern "C" fn(
arg1: *mut ffi_cif,
arg2: *mut c_void,
arg3: *mut *mut c_void,
arg4: *mut c_void,
),
>,
pub this_closure: *mut c_void,
pub fun: Option<
unsafe extern "C" fn(
arg1: *mut ffi_cif,
arg2: *mut c_void,
arg3: *mut ffi_java_raw,
arg4: *mut c_void,
),
>,
pub user_data: *mut c_void,
}
impl Default for ffi_java_raw_closure {
fn default() -> Self {
unsafe { zeroed() }
}
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ffi_go_closure {
pub tramp: *mut c_void,
pub cif: *mut ffi_cif,
pub fun: Option<
unsafe extern "C" fn(
arg1: *mut ffi_cif,
arg2: *mut c_void,
arg3: *mut *mut c_void,
arg4: *mut c_void,
),
>,
}
impl Default for ffi_go_closure {
fn default() -> Self {
unsafe { zeroed() }
}
}
extern "C" {
pub static mut ffi_type_void: ffi_type;
pub static mut ffi_type_uint8: ffi_type;
pub static mut ffi_type_sint8: ffi_type;
pub static mut ffi_type_uint16: ffi_type;
pub static mut ffi_type_sint16: ffi_type;
pub static mut ffi_type_uint32: ffi_type;
pub static mut ffi_type_sint32: ffi_type;
pub static mut ffi_type_uint64: ffi_type;
pub static mut ffi_type_sint64: ffi_type;
pub static mut ffi_type_float: ffi_type;
pub static mut ffi_type_double: ffi_type;
pub static mut ffi_type_pointer: ffi_type;
#[cfg(not(all(target_arch = "arm", target_os = "linux", target_env = "gnu")))]
pub static mut ffi_type_longdouble: ffi_type;
#[cfg(feature = "complex")]
pub static mut ffi_type_complex_float: ffi_type;
#[cfg(feature = "complex")]
pub static mut ffi_type_complex_double: ffi_type;
#[cfg(feature = "complex")]
#[cfg(not(all(target_arch = "arm", target_os = "linux", target_env = "gnu")))]
pub static mut ffi_type_complex_longdouble: ffi_type;
pub fn ffi_raw_call(
cif: *mut ffi_cif,
fn_: Option<unsafe extern "C" fn()>,
rvalue: *mut c_void,
avalue: *mut ffi_raw,
);
pub fn ffi_ptrarray_to_raw(cif: *mut ffi_cif, args: *mut *mut c_void, raw: *mut ffi_raw);
pub fn ffi_raw_to_ptrarray(cif: *mut ffi_cif, raw: *mut ffi_raw, args: *mut *mut c_void);
pub fn ffi_raw_size(cif: *mut ffi_cif) -> usize;
pub fn ffi_java_raw_call(
cif: *mut ffi_cif,
fn_: Option<unsafe extern "C" fn()>,
rvalue: *mut c_void,
avalue: *mut ffi_java_raw,
);
pub fn ffi_java_ptrarray_to_raw(
cif: *mut ffi_cif,
args: *mut *mut c_void,
raw: *mut ffi_java_raw,
);
pub fn ffi_java_raw_to_ptrarray(
cif: *mut ffi_cif,
raw: *mut ffi_java_raw,
args: *mut *mut c_void,
);
pub fn ffi_java_raw_size(cif: *mut ffi_cif) -> usize;
pub fn ffi_closure_alloc(size: usize, code: *mut *mut c_void) -> *mut c_void;
pub fn ffi_closure_free(arg1: *mut c_void);
pub fn ffi_prep_closure(
arg1: *mut ffi_closure,
arg2: *mut ffi_cif,
fun: Option<
unsafe extern "C" fn(
arg1: *mut ffi_cif,
arg2: *mut c_void,
arg3: *mut *mut c_void,
arg4: *mut c_void,
),
>,
user_data: *mut c_void,
) -> ffi_status;
pub fn ffi_prep_closure_loc(
arg1: *mut ffi_closure,
arg2: *mut ffi_cif,
fun: Option<
unsafe extern "C" fn(
arg1: *mut ffi_cif,
arg2: *mut c_void,
arg3: *mut *mut c_void,
arg4: *mut c_void,
),
>,
user_data: *mut c_void,
codeloc: *mut c_void,
) -> ffi_status;
pub fn ffi_prep_raw_closure(
arg1: *mut ffi_raw_closure,
cif: *mut ffi_cif,
fun: Option<
unsafe extern "C" fn(
arg1: *mut ffi_cif,
arg2: *mut c_void,
arg3: *mut ffi_raw,
arg4: *mut c_void,
),
>,
user_data: *mut c_void,
) -> ffi_status;
pub fn ffi_prep_raw_closure_loc(
arg1: *mut ffi_raw_closure,
cif: *mut ffi_cif,
fun: Option<
unsafe extern "C" fn(
arg1: *mut ffi_cif,
arg2: *mut c_void,
arg3: *mut ffi_raw,
arg4: *mut c_void,
),
>,
user_data: *mut c_void,
codeloc: *mut c_void,
) -> ffi_status;
pub fn ffi_prep_java_raw_closure(
arg1: *mut ffi_java_raw_closure,
cif: *mut ffi_cif,
fun: Option<
unsafe extern "C" fn(
arg1: *mut ffi_cif,
arg2: *mut c_void,
arg3: *mut ffi_java_raw,
arg4: *mut c_void,
),
>,
user_data: *mut c_void,
) -> ffi_status;
pub fn ffi_prep_java_raw_closure_loc(
arg1: *mut ffi_java_raw_closure,
cif: *mut ffi_cif,
fun: Option<
unsafe extern "C" fn(
arg1: *mut ffi_cif,
arg2: *mut c_void,
arg3: *mut ffi_java_raw,
arg4: *mut c_void,
),
>,
user_data: *mut c_void,
codeloc: *mut c_void,
) -> ffi_status;
pub fn ffi_prep_go_closure(
arg1: *mut ffi_go_closure,
arg2: *mut ffi_cif,
fun: Option<
unsafe extern "C" fn(
arg1: *mut ffi_cif,
arg2: *mut c_void,
arg3: *mut *mut c_void,
arg4: *mut c_void,
),
>,
) -> ffi_status;
pub fn ffi_call_go(
cif: *mut ffi_cif,
fn_: Option<unsafe extern "C" fn()>,
rvalue: *mut c_void,
avalue: *mut *mut c_void,
closure: *mut c_void,
);
pub fn ffi_prep_cif(
cif: *mut ffi_cif,
abi: ffi_abi,
nargs: c_uint,
rtype: *mut ffi_type,
atypes: *mut *mut ffi_type,
) -> ffi_status;
pub fn ffi_prep_cif_var(
cif: *mut ffi_cif,
abi: ffi_abi,
nfixedargs: c_uint,
ntotalargs: c_uint,
rtype: *mut ffi_type,
atypes: *mut *mut ffi_type,
) -> ffi_status;
pub fn ffi_call(
cif: *mut ffi_cif,
fn_: Option<unsafe extern "C" fn()>,
rvalue: *mut c_void,
avalue: *mut *mut c_void,
);
pub fn ffi_get_struct_offsets(
abi: ffi_abi,
struct_type: *mut ffi_type,
offsets: *mut usize,
) -> ffi_status;
}
#[cfg(test)]
mod test {
use super::*;
extern "C" fn add(x: u64, y: u64) -> u64 {
x + y
}
#[test]
fn test_function_with_two_arguments() {
unsafe {
let mut cif: ffi_cif = Default::default();
let mut arg_types: Vec<*mut ffi_type> =
vec![&mut ffi_type_uint64, &mut ffi_type_uint64];
let prep_status = ffi_prep_cif(
&mut cif,
ffi_abi_FFI_DEFAULT_ABI,
2,
&mut ffi_type_uint64,
arg_types.as_mut_ptr(),
);
assert_eq!(prep_status, ffi_status_FFI_OK);
let mut rval = 0u64;
let func = &*(&(add as *mut extern "C" fn(u64, u64) -> u64) as *const _
as *const extern "C" fn());
ffi_call(
&mut cif,
Some(*func),
&mut rval as *mut _ as *mut c_void,
vec![
&mut 4u64 as *mut _ as *mut c_void,
&mut 5u64 as *mut _ as *mut c_void,
]
.as_mut_ptr(),
);
assert_eq!(rval, 9);
}
}
}