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
FieldsModifier and TypeFieldDescriptionstatic final intStatus codes.static final intStatus codes.static final intStatus codes.static final intABI enumeration.static final intABI enumeration.static final intABI enumeration.static final intABI enumeration.static final intABI enumeration.static final intABI enumeration.static final intABI enumeration.static final intStatus codes.static final intABI enumeration.static final intABI enumeration.static final intABI enumeration.static final intABI enumeration.static final intABI enumeration.static final FFITypeTheffi_type_doublestruct.static final shortTypes used to create customFFICIF.static final FFITypeTheffi_type_floatstruct.static final shortTypes used to create customFFICIF.static final shortTypes used to create customFFICIF.static final FFITypeTheffi_type_longdoublestruct.static final shortTypes used to create customFFICIF.static final FFITypeTheffi_type_pointerstruct.static final shortTypes used to create customFFICIF.static final FFITypeTheffi_type_scharstruct.static final FFITypeTheffi_type_sintstruct.static final FFITypeTheffi_type_sint16struct.static final shortTypes used to create customFFICIF.static final FFITypeTheffi_type_sint32struct.static final shortTypes used to create customFFICIF.static final FFITypeTheffi_type_sint64struct.static final shortTypes used to create customFFICIF.static final FFITypeTheffi_type_sint8struct.static final shortTypes used to create customFFICIF.static final FFITypeTheffi_type_slongstruct.static final FFITypeTheffi_type_sshortstruct.static final shortTypes used to create customFFICIF.static final FFITypeTheffi_type_ucharstruct.static final FFITypeTheffi_type_uintstruct.static final FFITypeTheffi_type_uint16struct.static final shortTypes used to create customFFICIF.static final FFITypeTheffi_type_uint32struct.static final shortTypes used to create customFFICIF.static final FFITypeTheffi_type_uint64struct.static final shortTypes used to create customFFICIF.static final FFITypeTheffi_type_uint8struct.static final shortTypes used to create customFFICIF.static final FFITypeTheffi_type_ulongstruct.static final FFITypeTheffi_type_ushortstruct.static final FFITypeTheffi_type_voidstruct.static final shortTypes used to create customFFICIF.static final intABI enumeration.static final intABI enumeration.static final intABI enumeration. -
Method Summary
Modifier and TypeMethodDescriptionstatic voidffi_call(FFICIF cif, long fn, @Nullable ByteBuffer rvalue, @Nullable org.lwjgl.PointerBuffer avalues) Calls the functionfnaccording to the description given incif.static @Nullable FFIClosureffi_closure_alloc(long size, org.lwjgl.PointerBuffer code) Allocates a chunk of memory holdingsizebytes.static voidffi_closure_free(FFIClosure writable) Frees memory allocated usingclosure_alloc.static intffi_get_struct_offsets(int abi, FFIType struct_type, @Nullable org.lwjgl.PointerBuffer offsets) Computes the offset of each element of the given structure type.static intffi_prep_cif(FFICIF cif, int abi, FFIType rtype, @Nullable org.lwjgl.PointerBuffer atypes) Initializes the specified Call Interface (CIF) according to the given parameters.static intffi_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 intffi_prep_closure_loc(FFIClosure closure, FFICIF cif, long fun, long user_data, long codeloc) Prepares a closure function.static voidnffi_call(long cif, long fn, long rvalue, long avalues) Unsafe version of:callstatic longnffi_closure_alloc(long size, long code) Unsafe version of:closure_allocstatic voidnffi_closure_free(long writable) Unsafe version of:closure_freestatic intnffi_get_struct_offsets(int abi, long struct_type, long offsets) Unsafe version of:get_struct_offsetsstatic intnffi_prep_cif(long cif, int abi, int nargs, long rtype, long atypes) Unsafe version of:prep_cifstatic intnffi_prep_cif_var(long cif, int abi, int nfixedargs, int ntotalargs, long rtype, long atypes) Unsafe version of:prep_cif_varstatic intnffi_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_voidstruct. -
ffi_type_uint8
Theffi_type_uint8struct. -
ffi_type_sint8
Theffi_type_sint8struct. -
ffi_type_uint16
Theffi_type_uint16struct. -
ffi_type_sint16
Theffi_type_sint16struct. -
ffi_type_uint32
Theffi_type_uint32struct. -
ffi_type_sint32
Theffi_type_sint32struct. -
ffi_type_uint64
Theffi_type_uint64struct. -
ffi_type_sint64
Theffi_type_sint64struct. -
ffi_type_uchar
Theffi_type_ucharstruct. -
ffi_type_schar
Theffi_type_scharstruct. -
ffi_type_ushort
Theffi_type_ushortstruct. -
ffi_type_sshort
Theffi_type_sshortstruct. -
ffi_type_uint
Theffi_type_uintstruct. -
ffi_type_sint
Theffi_type_sintstruct. -
ffi_type_ulong
Theffi_type_ulongstruct. -
ffi_type_slong
Theffi_type_slongstruct. -
ffi_type_float
Theffi_type_floatstruct. -
ffi_type_double
Theffi_type_doublestruct. -
ffi_type_longdouble
Theffi_type_longdoublestruct. -
ffi_type_pointer
Theffi_type_pointerstruct.
-
-
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_cifholds pointers to all theffi_typeobjects 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_cifstructure to prepareabi- the ABI to use; normallyDEFAULT_ABIis what you want. One of:FIRST_ABIWIN64GNUW64UNIX64EFI64SYSVSTDCALLTHISCALLFASTCALLMS_CDECLPASCALREGISTERVFPLAST_ABIDEFAULT_ABIrtype- a pointer to anffi_typestructure that describes the return type of the functionatypes- a vector offfi_typepointers.atypesmust havenargselements. Ifnargsis 0, this argument is ignored.- Returns:
- a status code, of type
ffi_status.This will be either
OKif everything worked properly;BAD_TYPEDEFif one of theffi_typeobjects is incorrect; orBAD_ABIif 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_varwithnfixedargs == ntotalargsis NOT equivalent to a call toprep_cif.The resulting
ffi_cifholds pointers to all theffi_typeobjects 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_cifstructure to prepareabi- the ABI to use; normallyDEFAULT_ABIis what you want. One of:FIRST_ABIWIN64GNUW64UNIX64EFI64SYSVSTDCALLTHISCALLFASTCALLMS_CDECLPASCALREGISTERVFPLAST_ABIDEFAULT_ABInfixedargs- the number of fixed arguments, prior to any variadic arguments. It must be greater than zero.rtype- a pointer to anffi_typestructure that describes the return type of the functionatypes- a vector offfi_typepointers.atypesmust haventotalargselements.- Returns:
- a status code, of type
ffi_status.This will be either
OKif everything worked properly;BAD_TYPEDEFif one of theffi_typeobjects is incorrect; orBAD_ABIif 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 functionfnaccording to the description given incif.cifmust have already been prepared usingprep_cif.- Parameters:
cif- aFFICIFstructure. It must be initialized withprep_ciforprep_cif_varbefore 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), thenrvalueis 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_arginto the return value.avalues- a vector ofvoid *pointers that point to the memory locations holding the argument values for a call.If
cifdeclares that the function has no arguments (i.e.,nargswas 0), thenavaluesis 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 inavaluesshould point to an object declared asshort; but if the return type isshort, thenrvalueshould 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. IfoffsetsisNULL, 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
OKon success;BAD_ABIifabiis invalid; orBAD_TYPEDEFifstruct_typeis invalid in some way. Note that onlyFFI_STRUCTtypes 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 holdingsizebytes.Returns a pointer to the writable address, and sets
*codeto the corresponding executable address.- Parameters:
size- the number of bytes to allocate. Should be sufficient to hold anffi_closureobject (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 anFFIClosurestructure
-
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 castcodelocto the appropriate pointer-to-function type.- Parameters:
closure- the address of anffi_closureobject; this is the writable address returned byclosure_alloc.cif- theffi_cifdescribing the function parametersfun- the function which will be called when the closure is invoked. It is called with the arguments:cif- Theffi_cifpassed 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,
funmust fill the object to which this points, following the same special promotion behavior asffi_call. That is, in most cases,retpoints to an object of exactly the size of the type specified whencifwas constructed. However, integral types narrower than the system register size are widened. In these cases your program may assume thatretpoints to anffi_argobject.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:
OKif everything went ok, and one of the otherffi_statusvalues on error
-