Class LibFFI
The foreign function interface provides a mechanism by which a function can generate a call to another function at runtime without requiring knowledge of the called function's interface at compile time. This enables use of native libraries that LWJGL does not provide bindings for.
libffi assumes that you have a pointer to the function you wish to call and that you know the number and types of arguments to pass it, as well as the return type of the function.
The first thing you must do is create an FFICIF
object that matches the signature of the function you wish to call. This is a separate step
because it is common to make multiple calls using a single FFICIF
. The cif
in ffi_cif
stands for Call InterFace. To prepare a
call interface object, use the function prep_cif
. To call a function using an initialized ffi_cif
, use the call
function.
-
Field Summary
Modifier and TypeFieldDescriptionstatic final int
Status codes.static final int
Status codes.static final int
Status codes.static final int
ABI enumeration.static final int
ABI enumeration.static final int
ABI enumeration.static final int
ABI enumeration.static final int
ABI enumeration.static final int
ABI enumeration.static final int
ABI enumeration.static final int
Status codes.static final int
ABI enumeration.static final int
ABI enumeration.static final int
ABI enumeration.static final int
ABI enumeration.static final int
ABI enumeration.static final FFIType
Theffi_type_double
struct.static final short
Types used to create customFFICIF
.static final FFIType
Theffi_type_float
struct.static final short
Types used to create customFFICIF
.static final short
Types used to create customFFICIF
.static final FFIType
Theffi_type_longdouble
struct.static final short
Types used to create customFFICIF
.static final FFIType
Theffi_type_pointer
struct.static final short
Types used to create customFFICIF
.static final FFIType
Theffi_type_schar
struct.static final FFIType
Theffi_type_sint
struct.static final FFIType
Theffi_type_sint16
struct.static final short
Types used to create customFFICIF
.static final FFIType
Theffi_type_sint32
struct.static final short
Types used to create customFFICIF
.static final FFIType
Theffi_type_sint64
struct.static final short
Types used to create customFFICIF
.static final FFIType
Theffi_type_sint8
struct.static final short
Types used to create customFFICIF
.static final FFIType
Theffi_type_slong
struct.static final FFIType
Theffi_type_sshort
struct.static final short
Types used to create customFFICIF
.static final FFIType
Theffi_type_uchar
struct.static final FFIType
Theffi_type_uint
struct.static final FFIType
Theffi_type_uint16
struct.static final short
Types used to create customFFICIF
.static final FFIType
Theffi_type_uint32
struct.static final short
Types used to create customFFICIF
.static final FFIType
Theffi_type_uint64
struct.static final short
Types used to create customFFICIF
.static final FFIType
Theffi_type_uint8
struct.static final short
Types used to create customFFICIF
.static final FFIType
Theffi_type_ulong
struct.static final FFIType
Theffi_type_ushort
struct.static final FFIType
Theffi_type_void
struct.static final short
Types used to create customFFICIF
.static final int
ABI enumeration.static final int
ABI enumeration.static final int
ABI enumeration. -
Method Summary
Modifier and TypeMethodDescriptionstatic void
ffi_call
(FFICIF cif, long fn, ByteBuffer rvalue, org.lwjgl.PointerBuffer avalues) Calls the functionfn
according to the description given incif
.static FFIClosure
ffi_closure_alloc
(long size, org.lwjgl.PointerBuffer code) Allocates a chunk of memory holdingsize
bytes.static void
ffi_closure_free
(FFIClosure writable) Frees memory allocated usingclosure_alloc
.static int
ffi_get_struct_offsets
(int abi, FFIType struct_type, org.lwjgl.PointerBuffer offsets) Computes the offset of each element of the given structure type.static int
ffi_prep_cif
(FFICIF cif, int abi, FFIType rtype, org.lwjgl.PointerBuffer atypes) Initializes the specified Call Interface (CIF) according to the given parameters.static int
ffi_prep_cif_var
(FFICIF cif, int abi, int nfixedargs, FFIType rtype, org.lwjgl.PointerBuffer atypes) Initializes the specified Call Interface (CIF) according to the given parameters for a call to a variadic function.static int
ffi_prep_closure_loc
(FFIClosure closure, FFICIF cif, long fun, long user_data, long codeloc) Prepares a closure function.static void
nffi_call
(long cif, long fn, long rvalue, long avalues) Unsafe version of:call
static long
nffi_closure_alloc
(long size, long code) Unsafe version of:closure_alloc
static void
nffi_closure_free
(long writable) Unsafe version of:closure_free
static int
nffi_get_struct_offsets
(int abi, long struct_type, long offsets) Unsafe version of:get_struct_offsets
static int
nffi_prep_cif
(long cif, int abi, int nargs, long rtype, long atypes) Unsafe version of:prep_cif
static int
nffi_prep_cif_var
(long cif, int abi, int nfixedargs, int ntotalargs, long rtype, long atypes) Unsafe version of:prep_cif_var
static int
nffi_prep_closure_loc
(long closure, long cif, long fun, long user_data, long codeloc) Unsafe version of:prep_closure_loc
-
Field Details
-
FFI_TYPE_VOID
public static final short FFI_TYPE_VOIDTypes used to create customFFICIF
.- See Also:
-
FFI_TYPE_INT
public static final short FFI_TYPE_INTTypes used to create customFFICIF
.- See Also:
-
FFI_TYPE_FLOAT
public static final short FFI_TYPE_FLOATTypes used to create customFFICIF
.- See Also:
-
FFI_TYPE_DOUBLE
public static final short FFI_TYPE_DOUBLETypes used to create customFFICIF
.- See Also:
-
FFI_TYPE_LONGDOUBLE
public static final short FFI_TYPE_LONGDOUBLETypes used to create customFFICIF
. -
FFI_TYPE_UINT8
public static final short FFI_TYPE_UINT8Types used to create customFFICIF
.- See Also:
-
FFI_TYPE_SINT8
public static final short FFI_TYPE_SINT8Types used to create customFFICIF
.- See Also:
-
FFI_TYPE_UINT16
public static final short FFI_TYPE_UINT16Types used to create customFFICIF
.- See Also:
-
FFI_TYPE_SINT16
public static final short FFI_TYPE_SINT16Types used to create customFFICIF
.- See Also:
-
FFI_TYPE_UINT32
public static final short FFI_TYPE_UINT32Types used to create customFFICIF
.- See Also:
-
FFI_TYPE_SINT32
public static final short FFI_TYPE_SINT32Types used to create customFFICIF
.- See Also:
-
FFI_TYPE_UINT64
public static final short FFI_TYPE_UINT64Types used to create customFFICIF
.- See Also:
-
FFI_TYPE_SINT64
public static final short FFI_TYPE_SINT64Types used to create customFFICIF
.- See Also:
-
FFI_TYPE_STRUCT
public static final short FFI_TYPE_STRUCTTypes used to create customFFICIF
.- See Also:
-
FFI_TYPE_POINTER
public static final short FFI_TYPE_POINTERTypes used to create customFFICIF
.- See Also:
-
FFI_FIRST_ABI
public static final int FFI_FIRST_ABI -
FFI_WIN64
public static final int FFI_WIN64 -
FFI_GNUW64
public static final int FFI_GNUW64 -
FFI_UNIX64
public static final int FFI_UNIX64 -
FFI_EFI64
public static final int FFI_EFI64 -
FFI_SYSV
public static final int FFI_SYSV -
FFI_STDCALL
public static final int FFI_STDCALL -
FFI_THISCALL
public static final int FFI_THISCALL -
FFI_FASTCALL
public static final int FFI_FASTCALL -
FFI_MS_CDECL
public static final int FFI_MS_CDECL -
FFI_PASCAL
public static final int FFI_PASCAL -
FFI_REGISTER
public static final int FFI_REGISTER -
FFI_VFP
public static final int FFI_VFP -
FFI_LAST_ABI
public static final int FFI_LAST_ABI -
FFI_DEFAULT_ABI
public static final int FFI_DEFAULT_ABI -
FFI_OK
public static final int FFI_OKStatus codes.Enum values:
- See Also:
-
FFI_BAD_TYPEDEF
public static final int FFI_BAD_TYPEDEFStatus codes.Enum values:
- See Also:
-
FFI_BAD_ABI
public static final int FFI_BAD_ABIStatus codes.Enum values:
- See Also:
-
FFI_BAD_ARGTYPE
public static final int FFI_BAD_ARGTYPEStatus codes.Enum values:
- See Also:
-
ffi_type_void
Theffi_type_void
struct. -
ffi_type_uint8
Theffi_type_uint8
struct. -
ffi_type_sint8
Theffi_type_sint8
struct. -
ffi_type_uint16
Theffi_type_uint16
struct. -
ffi_type_sint16
Theffi_type_sint16
struct. -
ffi_type_uint32
Theffi_type_uint32
struct. -
ffi_type_sint32
Theffi_type_sint32
struct. -
ffi_type_uint64
Theffi_type_uint64
struct. -
ffi_type_sint64
Theffi_type_sint64
struct. -
ffi_type_uchar
Theffi_type_uchar
struct. -
ffi_type_schar
Theffi_type_schar
struct. -
ffi_type_ushort
Theffi_type_ushort
struct. -
ffi_type_sshort
Theffi_type_sshort
struct. -
ffi_type_uint
Theffi_type_uint
struct. -
ffi_type_sint
Theffi_type_sint
struct. -
ffi_type_ulong
Theffi_type_ulong
struct. -
ffi_type_slong
Theffi_type_slong
struct. -
ffi_type_float
Theffi_type_float
struct. -
ffi_type_double
Theffi_type_double
struct. -
ffi_type_longdouble
Theffi_type_longdouble
struct. -
ffi_type_pointer
Theffi_type_pointer
struct.
-
-
Method Details
-
nffi_prep_cif
public static int nffi_prep_cif(long cif, int abi, int nargs, long rtype, long atypes) Unsafe version of:prep_cif
- Parameters:
nargs
- the number of arguments that this function accepts
-
ffi_prep_cif
public static int ffi_prep_cif(FFICIF cif, int abi, FFIType rtype, @Nullable org.lwjgl.PointerBuffer atypes) Initializes the specified Call Interface (CIF) according to the given parameters.The resulting
ffi_cif
holds pointers to all theffi_type
objects that were used during initialization. You must ensure that these type objects have a lifetime at least as long as that of theffi_cif
.- Parameters:
cif
- theffi_cif
structure to prepareabi
- the ABI to use; normallyDEFAULT_ABI
is what you want. One of:FIRST_ABI
WIN64
GNUW64
UNIX64
EFI64
SYSV
STDCALL
THISCALL
FASTCALL
MS_CDECL
PASCAL
REGISTER
VFP
LAST_ABI
DEFAULT_ABI
rtype
- a pointer to anffi_type
structure that describes the return type of the functionatypes
- a vector offfi_type
pointers.atypes
must havenargs
elements. Ifnargs
is 0, this argument is ignored.- Returns:
- a status code, of type
ffi_status
.This will be either
OK
if everything worked properly;BAD_TYPEDEF
if one of theffi_type
objects is incorrect; orBAD_ABI
if the ABI parameter is invalid.
-
nffi_prep_cif_var
public static int nffi_prep_cif_var(long cif, int abi, int nfixedargs, int ntotalargs, long rtype, long atypes) Unsafe version of:prep_cif_var
- Parameters:
ntotalargs
- the total number of arguments, including variadic and fixed arguments
-
ffi_prep_cif_var
public static int ffi_prep_cif_var(FFICIF cif, int abi, int nfixedargs, FFIType rtype, org.lwjgl.PointerBuffer atypes) Initializes the specified Call Interface (CIF) according to the given parameters for a call to a variadic function.Different CIF's must be prepped for calls to the same function when different numbers of arguments are passed. A call to
ffi_prep_cif_var
withnfixedargs == ntotalargs
is NOT equivalent to a call toprep_cif
.The resulting
ffi_cif
holds pointers to all theffi_type
objects that were used during initialization. You must ensure that these type objects have a lifetime at least as long as that of theffi_cif
.- Parameters:
cif
- theffi_cif
structure to prepareabi
- the ABI to use; normallyDEFAULT_ABI
is what you want. One of:FIRST_ABI
WIN64
GNUW64
UNIX64
EFI64
SYSV
STDCALL
THISCALL
FASTCALL
MS_CDECL
PASCAL
REGISTER
VFP
LAST_ABI
DEFAULT_ABI
nfixedargs
- the number of fixed arguments, prior to any variadic arguments. It must be greater than zero.rtype
- a pointer to anffi_type
structure that describes the return type of the functionatypes
- a vector offfi_type
pointers.atypes
must haventotalargs
elements.- Returns:
- a status code, of type
ffi_status
.This will be either
OK
if everything worked properly;BAD_TYPEDEF
if one of theffi_type
objects is incorrect; orBAD_ABI
if the ABI parameter is invalid.
-
nffi_call
public static void nffi_call(long cif, long fn, long rvalue, long avalues) Unsafe version of:call
-
ffi_call
public static void ffi_call(FFICIF cif, long fn, @Nullable ByteBuffer rvalue, @Nullable org.lwjgl.PointerBuffer avalues) Calls the functionfn
according to the description given incif
.cif
must have already been prepared usingprep_cif
.- Parameters:
cif
- aFFICIF
structure. It must be initialized withprep_cif
orprep_cif_var
before it is used withffi_call
.fn
- the function to callrvalue
- a pointer to a chunk of memory that will hold the result of the function call.This must be large enough to hold the result, no smaller than the system register size (generally 32 or 64 bits), and must be suitably aligned; it is the caller's responsibility to ensure this. If CIF declares that the function returns
void
(usingtype_void
), thenrvalue
is ignored.In most situations, libffi will handle promotion according to the ABI. However, for historical reasons, there is a special case with return values that must be handled by your code. In particular, for integral (not
struct
) types that are narrower than the system register size, the return value will be widened by libffi. libffi provides a type,ffi_arg
, that can be used as the return type. For example, if the CIF was defined with a return type ofchar
, libffi will try to store a fullffi_arg
into the return value.avalues
- a vector ofvoid *
pointers that point to the memory locations holding the argument values for a call.If
cif
declares that the function has no arguments (i.e.,nargs
was 0), thenavalues
is ignored. Note that argument values may be modified by the callee (for instance, structs passed by value); the burden of copying pass-by-value arguments is placed on the caller.Note that while the return value must be register-sized, arguments should exactly match their declared type. For example, if an argument is a
short
, then the entry inavalues
should point to an object declared asshort
; but if the return type isshort
, thenrvalue
should point to an object declared as a larger type - usuallyffi_arg
.
-
nffi_get_struct_offsets
public static int nffi_get_struct_offsets(int abi, long struct_type, long offsets) Unsafe version of:get_struct_offsets
-
ffi_get_struct_offsets
public static int ffi_get_struct_offsets(int abi, FFIType struct_type, @Nullable org.lwjgl.PointerBuffer offsets) Computes the offset of each element of the given structure type.- Parameters:
abi
- the ABI to use; this is needed because in some cases the layout depends on the ABIoffsets
- an out parameter. The caller is responsible for providing enough space for all the results to be written - one element per element type instruct_type
. Ifoffsets
isNULL
, then the type will be laid out but not otherwise modified. This can be useful for accessing the type's size or layout.- Returns:
- returns
OK
on success;BAD_ABI
ifabi
is invalid; orBAD_TYPEDEF
ifstruct_type
is invalid in some way. Note that onlyFFI_STRUCT
types are valid here.
-
nffi_closure_alloc
public static long nffi_closure_alloc(long size, long code) Unsafe version of:closure_alloc
-
ffi_closure_alloc
Allocates a chunk of memory holdingsize
bytes.Returns a pointer to the writable address, and sets
*code
to the corresponding executable address.- Parameters:
size
- the number of bytes to allocate. Should be sufficient to hold anffi_closure
object (FFIClosure.SIZEOF
).code
- a buffer in which to place the returned executable address- Returns:
- a pointer to the writable address
-
nffi_closure_free
public static void nffi_closure_free(long writable) Unsafe version of:closure_free
-
ffi_closure_free
Frees memory allocated usingclosure_alloc
.- Parameters:
writable
- the address of anFFIClosure
structure
-
nffi_prep_closure_loc
public static int nffi_prep_closure_loc(long closure, long cif, long fun, long user_data, long codeloc) Unsafe version of:prep_closure_loc
-
ffi_prep_closure_loc
public static int ffi_prep_closure_loc(FFIClosure closure, FFICIF cif, long fun, long user_data, long codeloc) Prepares a closure function.After calling
ffi_prep_closure_loc,
you can castcodeloc
to the appropriate pointer-to-function type.- Parameters:
closure
- the address of anffi_closure
object; this is the writable address returned byclosure_alloc
.cif
- theffi_cif
describing the function parametersfun
- the function which will be called when the closure is invoked. It is called with the arguments:cif
- Theffi_cif
passed toffi_prep_closure_loc
.ret
- a pointer to the memory used for the function's return value.If the function is declared as returning
void
, then this value is garbage and should not be used.Otherwise,
fun
must fill the object to which this points, following the same special promotion behavior asffi_call
. That is, in most cases,ret
points to an object of exactly the size of the type specified whencif
was constructed. However, integral types narrower than the system register size are widened. In these cases your program may assume thatret
points to anffi_arg
object.args
- a vector of pointers to memory holding the arguments to the function.user_data
- the same USER_DATA that was passed toffi_prep_closure_loc
.
user_data
- an arbitrary datum that is passed, uninterpreted, to your closure functioncodeloc
- the executable address returned byclosure_alloc
.- Returns:
OK
if everything went ok, and one of the otherffi_status
values on error
-