mirror of
				https://github.com/openresty/openresty.git
				synced 2024-10-13 00:29:41 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1386 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1386 lines
		
	
	
		
			40 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
=pod
 | 
						|
 | 
						|
LuaJIT
 | 
						|
 | 
						|
=head1 FFI Semantics
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item * LuaJIT
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item * Download E<rchevron>
 | 
						|
 | 
						|
=item * Installation
 | 
						|
 | 
						|
=item * Running
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
=item * Extensions
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item * FFI Library
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item * FFI Tutorial
 | 
						|
 | 
						|
=item * ffi.* API
 | 
						|
 | 
						|
=item * FFI Semantics
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
=item * jit.* Library
 | 
						|
 | 
						|
=item * Lua/C API
 | 
						|
 | 
						|
=item * Profiler
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
=item * Status
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item * Changes
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
=item * FAQ
 | 
						|
 | 
						|
=item * Performance E<rchevron>
 | 
						|
 | 
						|
=item * Wiki E<rchevron>
 | 
						|
 | 
						|
=item * Mailing List E<rchevron>
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
This page describes the detailed semantics underlying the FFI library
 | 
						|
and its interaction with both Lua and C code.
 | 
						|
 | 
						|
Given that the FFI library is designed to interface with C code and
 | 
						|
that declarations can be written in plain C syntax, B<it closely
 | 
						|
follows the C language semantics>, wherever possible. Some minor
 | 
						|
concessions are needed for smoother interoperation with Lua language
 | 
						|
semantics.
 | 
						|
 | 
						|
Please don't be overwhelmed by the contents of this page E<mdash> this
 | 
						|
is a reference and you may need to consult it, if in doubt. It doesn't
 | 
						|
hurt to skim this page, but most of the semantics "just work" as you'd
 | 
						|
expect them to work. It should be straightforward to write applications
 | 
						|
using the LuaJIT FFI for developers with a C or C++ background.
 | 
						|
 | 
						|
=head2 C Language Support
 | 
						|
 | 
						|
The FFI library has a built-in C parser with a minimal memory
 | 
						|
footprint. It's used by the ffi.* library functions to declare C types
 | 
						|
or external symbols.
 | 
						|
 | 
						|
It's only purpose is to parse C declarations, as found e.g. in C header
 | 
						|
files. Although it does evaluate constant expressions, it's I<not> a C
 | 
						|
compiler. The body of C<inline> C function definitions is simply
 | 
						|
ignored.
 | 
						|
 | 
						|
Also, this is I<not> a validating C parser. It expects and accepts
 | 
						|
correctly formed C declarations, but it may choose to ignore bad
 | 
						|
declarations or show rather generic error messages. If in doubt, please
 | 
						|
check the input against your favorite C compiler.
 | 
						|
 | 
						|
The C parser complies to the B<C99 language standard> plus the
 | 
						|
following extensions:
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item * The C<'\e'> escape in character and string literals.
 | 
						|
 | 
						|
=item * The C99/C++ boolean type, declared with the keywords C<bool> or
 | 
						|
C<_Bool>.
 | 
						|
 | 
						|
=item * Complex numbers, declared with the keywords C<complex> or
 | 
						|
C<_Complex>.
 | 
						|
 | 
						|
=item * Two complex number types: C<complex> (aka C<complex double>)
 | 
						|
and C<complex float>.
 | 
						|
 | 
						|
=item * Vector types, declared with the GCC C<mode> or C<vector_size>
 | 
						|
attribute.
 | 
						|
 | 
						|
=item * Unnamed ('transparent') C<struct>/C<union> fields inside a
 | 
						|
C<struct>/C<union>.
 | 
						|
 | 
						|
=item * Incomplete C<enum> declarations, handled like incomplete
 | 
						|
C<struct> declarations.
 | 
						|
 | 
						|
=item * Unnamed C<enum> fields inside a C<struct>/C<union>. This is
 | 
						|
similar to a scoped C++ C<enum>, except that declared constants are
 | 
						|
visible in the global namespace, too.
 | 
						|
 | 
						|
=item * Scoped C<static const> declarations inside a C<struct>/C<union>
 | 
						|
(from C++).
 | 
						|
 | 
						|
=item * Zero-length arrays (C<[0]>), empty C<struct>/C<union>,
 | 
						|
variable-length arrays (VLA, C<[?]>) and variable-length structs (VLS,
 | 
						|
with a trailing VLA).
 | 
						|
 | 
						|
=item * C++ reference types (C<int &x>).
 | 
						|
 | 
						|
=item * Alternate GCC keywords with 'C<__>', e.g. C<__const__>.
 | 
						|
 | 
						|
=item * GCC C<__attribute__> with the following attributes: C<aligned>,
 | 
						|
C<packed>, C<mode>, C<vector_size>, C<cdecl>, C<fastcall>, C<stdcall>,
 | 
						|
C<thiscall>.
 | 
						|
 | 
						|
=item * The GCC C<__extension__> keyword and the GCC C<__alignof__>
 | 
						|
operator.
 | 
						|
 | 
						|
=item * GCC C<__asm__("symname")> symbol name redirection for function
 | 
						|
declarations.
 | 
						|
 | 
						|
=item * MSVC keywords for fixed-length types: C<__int8>, C<__int16>,
 | 
						|
C<__int32> and C<__int64>.
 | 
						|
 | 
						|
=item * MSVC C<__cdecl>, C<__fastcall>, C<__stdcall>, C<__thiscall>,
 | 
						|
C<__ptr32>, C<__ptr64>, C<__declspec(align(n))> and C<#pragma pack>.
 | 
						|
 | 
						|
=item * All other GCC/MSVC-specific attributes are ignored.
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
The following C types are pre-defined by the C parser (like a
 | 
						|
C<typedef>, except re-declarations will be ignored):
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item * Vararg handling: C<va_list>, C<__builtin_va_list>,
 | 
						|
C<__gnuc_va_list>.
 | 
						|
 | 
						|
=item * From C<E<lt>stddef.hE<gt>>: C<ptrdiff_t>, C<size_t>,
 | 
						|
C<wchar_t>.
 | 
						|
 | 
						|
=item * From C<E<lt>stdint.hE<gt>>: C<int8_t>, C<int16_t>, C<int32_t>,
 | 
						|
C<int64_t>, C<uint8_t>, C<uint16_t>, C<uint32_t>, C<uint64_t>,
 | 
						|
C<intptr_t>, C<uintptr_t>.
 | 
						|
 | 
						|
=item * From C<E<lt>unistd.hE<gt>> (POSIX): C<ssize_t>.
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
You're encouraged to use these types in preference to compiler-specific
 | 
						|
extensions or target-dependent standard types. E.g. C<char> differs in
 | 
						|
signedness and C<long> differs in size, depending on the target
 | 
						|
architecture and platform ABI.
 | 
						|
 | 
						|
The following C features are B<not> supported:
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item * A declaration must always have a type specifier; it doesn't
 | 
						|
default to an C<int> type.
 | 
						|
 | 
						|
=item * Old-style empty function declarations (K&R) are not allowed.
 | 
						|
All C functions must have a proper prototype declaration. A function
 | 
						|
declared without parameters (C<int foo();>) is treated as a function
 | 
						|
taking zero arguments, like in C++.
 | 
						|
 | 
						|
=item * The C<long double> C type is parsed correctly, but there's no
 | 
						|
support for the related conversions, accesses or arithmetic operations.
 | 
						|
 | 
						|
=item * Wide character strings and character literals are not
 | 
						|
supported.
 | 
						|
 | 
						|
=item * See below for features that are currently not implemented.
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
=head2 C Type Conversion Rules
 | 
						|
 | 
						|
=head2 Conversions from C types to Lua objects
 | 
						|
 | 
						|
These conversion rules apply for I<read accesses> to C types: indexing
 | 
						|
pointers, arrays or C<struct>/C<union> types; reading external
 | 
						|
variables or constant values; retrieving return values from C calls:
 | 
						|
 | 
						|
Input
 | 
						|
 | 
						|
Conversion
 | 
						|
 | 
						|
Output
 | 
						|
 | 
						|
C<int8_t>, C<int16_t>
 | 
						|
 | 
						|
E<rarr>sign-ext C<int32_t> E<rarr> C<double>
 | 
						|
 | 
						|
number
 | 
						|
 | 
						|
C<uint8_t>, C<uint16_t>
 | 
						|
 | 
						|
E<rarr>zero-ext C<int32_t> E<rarr> C<double>
 | 
						|
 | 
						|
number
 | 
						|
 | 
						|
C<int32_t>, C<uint32_t>
 | 
						|
 | 
						|
E<rarr> C<double>
 | 
						|
 | 
						|
number
 | 
						|
 | 
						|
C<int64_t>, C<uint64_t>
 | 
						|
 | 
						|
boxed value
 | 
						|
 | 
						|
64 bit int cdata
 | 
						|
 | 
						|
C<double>, C<float>
 | 
						|
 | 
						|
E<rarr> C<double>
 | 
						|
 | 
						|
number
 | 
						|
 | 
						|
C<bool>
 | 
						|
 | 
						|
0 E<rarr> C<false>, otherwise C<true>
 | 
						|
 | 
						|
boolean
 | 
						|
 | 
						|
C<enum>
 | 
						|
 | 
						|
boxed value
 | 
						|
 | 
						|
enum cdata
 | 
						|
 | 
						|
Complex number
 | 
						|
 | 
						|
boxed value
 | 
						|
 | 
						|
complex cdata
 | 
						|
 | 
						|
Vector
 | 
						|
 | 
						|
boxed value
 | 
						|
 | 
						|
vector cdata
 | 
						|
 | 
						|
Pointer
 | 
						|
 | 
						|
boxed value
 | 
						|
 | 
						|
pointer cdata
 | 
						|
 | 
						|
Array
 | 
						|
 | 
						|
boxed reference
 | 
						|
 | 
						|
reference cdata
 | 
						|
 | 
						|
C<struct>/C<union>
 | 
						|
 | 
						|
boxed reference
 | 
						|
 | 
						|
reference cdata
 | 
						|
 | 
						|
Bitfields are treated like their underlying type.
 | 
						|
 | 
						|
Reference types are dereferenced I<before> a conversion can take place
 | 
						|
E<mdash> the conversion is applied to the C type pointed to by the
 | 
						|
reference.
 | 
						|
 | 
						|
=head2 Conversions from Lua objects to C types
 | 
						|
 | 
						|
These conversion rules apply for I<write accesses> to C types: indexing
 | 
						|
pointers, arrays or C<struct>/C<union> types; initializing cdata
 | 
						|
objects; casts to C types; writing to external variables; passing
 | 
						|
arguments to C calls:
 | 
						|
 | 
						|
Input
 | 
						|
 | 
						|
Conversion
 | 
						|
 | 
						|
Output
 | 
						|
 | 
						|
number
 | 
						|
 | 
						|
E<rarr>
 | 
						|
 | 
						|
C<double>
 | 
						|
 | 
						|
boolean
 | 
						|
 | 
						|
C<false> E<rarr> 0, C<true> E<rarr> 1
 | 
						|
 | 
						|
C<bool>
 | 
						|
 | 
						|
nil
 | 
						|
 | 
						|
C<NULL> E<rarr>
 | 
						|
 | 
						|
C<(void *)>
 | 
						|
 | 
						|
lightuserdata
 | 
						|
 | 
						|
lightuserdata address E<rarr>
 | 
						|
 | 
						|
C<(void *)>
 | 
						|
 | 
						|
userdata
 | 
						|
 | 
						|
userdata payload E<rarr>
 | 
						|
 | 
						|
C<(void *)>
 | 
						|
 | 
						|
io.* file
 | 
						|
 | 
						|
get FILE * handle E<rarr>
 | 
						|
 | 
						|
C<(void *)>
 | 
						|
 | 
						|
string
 | 
						|
 | 
						|
match against C<enum> constant
 | 
						|
 | 
						|
C<enum>
 | 
						|
 | 
						|
string
 | 
						|
 | 
						|
copy string data + zero-byte
 | 
						|
 | 
						|
C<int8_t[]>, C<uint8_t[]>
 | 
						|
 | 
						|
string
 | 
						|
 | 
						|
string data E<rarr>
 | 
						|
 | 
						|
C<const char[]>
 | 
						|
 | 
						|
function
 | 
						|
 | 
						|
create callback E<rarr>
 | 
						|
 | 
						|
C function type
 | 
						|
 | 
						|
table
 | 
						|
 | 
						|
table initializer
 | 
						|
 | 
						|
Array
 | 
						|
 | 
						|
table
 | 
						|
 | 
						|
table initializer
 | 
						|
 | 
						|
C<struct>/C<union>
 | 
						|
 | 
						|
cdata
 | 
						|
 | 
						|
cdata payload E<rarr>
 | 
						|
 | 
						|
C type
 | 
						|
 | 
						|
If the result type of this conversion doesn't match the C type of the
 | 
						|
destination, the conversion rules between C types are applied.
 | 
						|
 | 
						|
Reference types are immutable after initialization ("no re-seating of
 | 
						|
references"). For initialization purposes or when passing values to
 | 
						|
reference parameters, they are treated like pointers. Note that unlike
 | 
						|
in C++, there's no way to implement automatic reference generation of
 | 
						|
variables under the Lua language semantics. If you want to call a
 | 
						|
function with a reference parameter, you need to explicitly pass a
 | 
						|
one-element array.
 | 
						|
 | 
						|
=head2 Conversions between C types
 | 
						|
 | 
						|
These conversion rules are more or less the same as the standard C
 | 
						|
conversion rules. Some rules only apply to casts, or require pointer or
 | 
						|
type compatibility:
 | 
						|
 | 
						|
Input
 | 
						|
 | 
						|
Conversion
 | 
						|
 | 
						|
Output
 | 
						|
 | 
						|
Signed integer
 | 
						|
 | 
						|
E<rarr>narrow or sign-extend
 | 
						|
 | 
						|
Integer
 | 
						|
 | 
						|
Unsigned integer
 | 
						|
 | 
						|
E<rarr>narrow or zero-extend
 | 
						|
 | 
						|
Integer
 | 
						|
 | 
						|
Integer
 | 
						|
 | 
						|
E<rarr>round
 | 
						|
 | 
						|
C<double>, C<float>
 | 
						|
 | 
						|
C<double>, C<float>
 | 
						|
 | 
						|
E<rarr>trunc C<int32_t> E<rarr>narrow
 | 
						|
 | 
						|
C<(u)int8_t>, C<(u)int16_t>
 | 
						|
 | 
						|
C<double>, C<float>
 | 
						|
 | 
						|
E<rarr>trunc
 | 
						|
 | 
						|
C<(u)int32_t>, C<(u)int64_t>
 | 
						|
 | 
						|
C<double>, C<float>
 | 
						|
 | 
						|
E<rarr>round
 | 
						|
 | 
						|
C<float>, C<double>
 | 
						|
 | 
						|
Number
 | 
						|
 | 
						|
n == 0 E<rarr> 0, otherwise 1
 | 
						|
 | 
						|
C<bool>
 | 
						|
 | 
						|
C<bool>
 | 
						|
 | 
						|
C<false> E<rarr> 0, C<true> E<rarr> 1
 | 
						|
 | 
						|
Number
 | 
						|
 | 
						|
Complex number
 | 
						|
 | 
						|
convert real part
 | 
						|
 | 
						|
Number
 | 
						|
 | 
						|
Number
 | 
						|
 | 
						|
convert real part, imag = 0
 | 
						|
 | 
						|
Complex number
 | 
						|
 | 
						|
Complex number
 | 
						|
 | 
						|
convert real and imag part
 | 
						|
 | 
						|
Complex number
 | 
						|
 | 
						|
Number
 | 
						|
 | 
						|
convert scalar and replicate
 | 
						|
 | 
						|
Vector
 | 
						|
 | 
						|
Vector
 | 
						|
 | 
						|
copy (same size)
 | 
						|
 | 
						|
Vector
 | 
						|
 | 
						|
C<struct>/C<union>
 | 
						|
 | 
						|
take base address (compat)
 | 
						|
 | 
						|
Pointer
 | 
						|
 | 
						|
Array
 | 
						|
 | 
						|
take base address (compat)
 | 
						|
 | 
						|
Pointer
 | 
						|
 | 
						|
Function
 | 
						|
 | 
						|
take function address
 | 
						|
 | 
						|
Function pointer
 | 
						|
 | 
						|
Number
 | 
						|
 | 
						|
convert via C<uintptr_t> (cast)
 | 
						|
 | 
						|
Pointer
 | 
						|
 | 
						|
Pointer
 | 
						|
 | 
						|
convert address (compat/cast)
 | 
						|
 | 
						|
Pointer
 | 
						|
 | 
						|
Pointer
 | 
						|
 | 
						|
convert address (cast)
 | 
						|
 | 
						|
Integer
 | 
						|
 | 
						|
Array
 | 
						|
 | 
						|
convert base address (cast)
 | 
						|
 | 
						|
Integer
 | 
						|
 | 
						|
Array
 | 
						|
 | 
						|
copy (compat)
 | 
						|
 | 
						|
Array
 | 
						|
 | 
						|
C<struct>/C<union>
 | 
						|
 | 
						|
copy (identical type)
 | 
						|
 | 
						|
C<struct>/C<union>
 | 
						|
 | 
						|
Bitfields or C<enum> types are treated like their underlying type.
 | 
						|
 | 
						|
Conversions not listed above will raise an error. E.g. it's not
 | 
						|
possible to convert a pointer to a complex number or vice versa.
 | 
						|
 | 
						|
=head2 Conversions for vararg C function arguments
 | 
						|
 | 
						|
The following default conversion rules apply when passing Lua objects
 | 
						|
to the variable argument part of vararg C functions:
 | 
						|
 | 
						|
Input
 | 
						|
 | 
						|
Conversion
 | 
						|
 | 
						|
Output
 | 
						|
 | 
						|
number
 | 
						|
 | 
						|
E<rarr>
 | 
						|
 | 
						|
C<double>
 | 
						|
 | 
						|
boolean
 | 
						|
 | 
						|
C<false> E<rarr> 0, C<true> E<rarr> 1
 | 
						|
 | 
						|
C<bool>
 | 
						|
 | 
						|
nil
 | 
						|
 | 
						|
C<NULL> E<rarr>
 | 
						|
 | 
						|
C<(void *)>
 | 
						|
 | 
						|
userdata
 | 
						|
 | 
						|
userdata payload E<rarr>
 | 
						|
 | 
						|
C<(void *)>
 | 
						|
 | 
						|
lightuserdata
 | 
						|
 | 
						|
lightuserdata address E<rarr>
 | 
						|
 | 
						|
C<(void *)>
 | 
						|
 | 
						|
string
 | 
						|
 | 
						|
string data E<rarr>
 | 
						|
 | 
						|
C<const char *>
 | 
						|
 | 
						|
C<float> cdata
 | 
						|
 | 
						|
E<rarr>
 | 
						|
 | 
						|
C<double>
 | 
						|
 | 
						|
Array cdata
 | 
						|
 | 
						|
take base address
 | 
						|
 | 
						|
Element pointer
 | 
						|
 | 
						|
C<struct>/C<union> cdata
 | 
						|
 | 
						|
take base address
 | 
						|
 | 
						|
C<struct>/C<union> pointer
 | 
						|
 | 
						|
Function cdata
 | 
						|
 | 
						|
take function address
 | 
						|
 | 
						|
Function pointer
 | 
						|
 | 
						|
Any other cdata
 | 
						|
 | 
						|
no conversion
 | 
						|
 | 
						|
C type
 | 
						|
 | 
						|
To pass a Lua object, other than a cdata object, as a specific type,
 | 
						|
you need to override the conversion rules: create a temporary cdata
 | 
						|
object with a constructor or a cast and initialize it with the value to
 | 
						|
pass:
 | 
						|
 | 
						|
Assuming C<x> is a Lua number, here's how to pass it as an integer to a
 | 
						|
vararg function:
 | 
						|
 | 
						|
 ffi.cdef[[
 | 
						|
 int printf(const char *fmt, ...);
 | 
						|
 ]]
 | 
						|
 ffi.C.printf("integer value: %d\n", ffi.new("int", x))
 | 
						|
 | 
						|
If you don't do this, the default Lua number E<rarr> C<double>
 | 
						|
conversion rule applies. A vararg C function expecting an integer will
 | 
						|
see a garbled or uninitialized value.
 | 
						|
 | 
						|
=head2 Initializers
 | 
						|
 | 
						|
Creating a cdata object with C<ffi.new()> or the equivalent constructor
 | 
						|
syntax always initializes its contents, too. Different rules apply,
 | 
						|
depending on the number of optional initializers and the C types
 | 
						|
involved:
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item * If no initializers are given, the object is filled with zero
 | 
						|
bytes.
 | 
						|
 | 
						|
=item * Scalar types (numbers and pointers) accept a single
 | 
						|
initializer. The Lua object is converted to the scalar C type.
 | 
						|
 | 
						|
=item * Valarrays (complex numbers and vectors) are treated like
 | 
						|
scalars when a single initializer is given. Otherwise they are treated
 | 
						|
like regular arrays.
 | 
						|
 | 
						|
=item * Aggregate types (arrays and structs) accept either a single
 | 
						|
cdata initializer of the same type (copy constructor), a single table
 | 
						|
initializer, or a flat list of initializers.
 | 
						|
 | 
						|
=item * The elements of an array are initialized, starting at index
 | 
						|
zero. If a single initializer is given for an array, it's repeated for
 | 
						|
all remaining elements. This doesn't happen if two or more initializers
 | 
						|
are given: all remaining uninitialized elements are filled with zero
 | 
						|
bytes.
 | 
						|
 | 
						|
=item * Byte arrays may also be initialized with a Lua string. This
 | 
						|
copies the whole string plus a terminating zero-byte. The copy stops
 | 
						|
early only if the array has a known, fixed size.
 | 
						|
 | 
						|
=item * The fields of a C<struct> are initialized in the order of their
 | 
						|
declaration. Uninitialized fields are filled with zero bytes.
 | 
						|
 | 
						|
=item * Only the first field of a C<union> can be initialized with a
 | 
						|
flat initializer.
 | 
						|
 | 
						|
=item * Elements or fields which are aggregates themselves are
 | 
						|
initialized with a I<single> initializer, but this may be a table
 | 
						|
initializer or a compatible aggregate.
 | 
						|
 | 
						|
=item * Excess initializers cause an error.
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
=head2 Table Initializers
 | 
						|
 | 
						|
The following rules apply if a Lua table is used to initialize an Array
 | 
						|
or a C<struct>/C<union>:
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item * If the table index C<[0]> is non-C<nil>, then the table is
 | 
						|
assumed to be zero-based. Otherwise it's assumed to be one-based.
 | 
						|
 | 
						|
=item * Array elements, starting at index zero, are initialized
 | 
						|
one-by-one with the consecutive table elements, starting at either
 | 
						|
index C<[0]> or C<[1]>. This process stops at the first C<nil> table
 | 
						|
element.
 | 
						|
 | 
						|
=item * If exactly one array element was initialized, it's repeated for
 | 
						|
all the remaining elements. Otherwise all remaining uninitialized
 | 
						|
elements are filled with zero bytes.
 | 
						|
 | 
						|
=item * The above logic only applies to arrays with a known fixed size.
 | 
						|
A VLA is only initialized with the element(s) given in the table.
 | 
						|
Depending on the use case, you may need to explicitly add a C<NULL> or
 | 
						|
C<0> terminator to a VLA.
 | 
						|
 | 
						|
=item * A C<struct>/C<union> can be initialized in the order of the
 | 
						|
declaration of its fields. Each field is initialized with consecutive
 | 
						|
table elements, starting at either index C<[0]> or C<[1]>. This process
 | 
						|
stops at the first C<nil> table element.
 | 
						|
 | 
						|
=item * Otherwise, if neither index C<[0]> nor C<[1]> is present, a
 | 
						|
C<struct>/C<union> is initialized by looking up each field name (as a
 | 
						|
string key) in the table. Each non-C<nil> value is used to initialize
 | 
						|
the corresponding field.
 | 
						|
 | 
						|
=item * Uninitialized fields of a C<struct> are filled with zero bytes,
 | 
						|
except for the trailing VLA of a VLS.
 | 
						|
 | 
						|
=item * Initialization of a C<union> stops after one field has been
 | 
						|
initialized. If no field has been initialized, the C<union> is filled
 | 
						|
with zero bytes.
 | 
						|
 | 
						|
=item * Elements or fields which are aggregates themselves are
 | 
						|
initialized with a I<single> initializer, but this may be a nested
 | 
						|
table initializer (or a compatible aggregate).
 | 
						|
 | 
						|
=item * Excess initializers for an array cause an error. Excess
 | 
						|
initializers for a C<struct>/C<union> are ignored. Unrelated table
 | 
						|
entries are ignored, too.
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
Example:
 | 
						|
 | 
						|
 local ffi = require("ffi")
 | 
						|
 
 | 
						|
 ffi.cdef[[
 | 
						|
 struct foo { int a, b; };
 | 
						|
 union bar { int i; double d; };
 | 
						|
 struct nested { int x; struct foo y; };
 | 
						|
 ]]
 | 
						|
 
 | 
						|
 ffi.new("int[3]", {})            --> 0, 0, 0
 | 
						|
 ffi.new("int[3]", {1})           --> 1, 1, 1
 | 
						|
 ffi.new("int[3]", {1,2})         --> 1, 2, 0
 | 
						|
 ffi.new("int[3]", {1,2,3})       --> 1, 2, 3
 | 
						|
 ffi.new("int[3]", {[0]=1})       --> 1, 1, 1
 | 
						|
 ffi.new("int[3]", {[0]=1,2})     --> 1, 2, 0
 | 
						|
 ffi.new("int[3]", {[0]=1,2,3})   --> 1, 2, 3
 | 
						|
 ffi.new("int[3]", {[0]=1,2,3,4}) --> error: too many initializers
 | 
						|
 
 | 
						|
 ffi.new("struct foo", {})            --> a = 0, b = 0
 | 
						|
 ffi.new("struct foo", {1})           --> a = 1, b = 0
 | 
						|
 ffi.new("struct foo", {1,2})         --> a = 1, b = 2
 | 
						|
 ffi.new("struct foo", {[0]=1,2})     --> a = 1, b = 2
 | 
						|
 ffi.new("struct foo", {b=2})         --> a = 0, b = 2
 | 
						|
 ffi.new("struct foo", {a=1,b=2,c=3}) --> a = 1, b = 2  'c' is ignored
 | 
						|
 
 | 
						|
 ffi.new("union bar", {})        --> i = 0, d = 0.0
 | 
						|
 ffi.new("union bar", {1})       --> i = 1, d = ?
 | 
						|
 ffi.new("union bar", {[0]=1,2}) --> i = 1, d = ?    '2' is ignored
 | 
						|
 ffi.new("union bar", {d=2})     --> i = ?, d = 2.0
 | 
						|
 
 | 
						|
 ffi.new("struct nested", {1,{2,3}})     --> x = 1, y.a = 2, y.b = 3
 | 
						|
 ffi.new("struct nested", {x=1,y={2,3}}) --> x = 1, y.a = 2, y.b = 3
 | 
						|
 | 
						|
=head2 Operations on cdata Objects
 | 
						|
 | 
						|
All of the standard Lua operators can be applied to cdata objects or a
 | 
						|
mix of a cdata object and another Lua object. The following list shows
 | 
						|
the pre-defined operations.
 | 
						|
 | 
						|
Reference types are dereferenced I<before> performing each of the
 | 
						|
operations below E<mdash> the operation is applied to the C type
 | 
						|
pointed to by the reference.
 | 
						|
 | 
						|
The pre-defined operations are always tried first before deferring to a
 | 
						|
metamethod or index table (if any) for the corresponding ctype (except
 | 
						|
for C<__new>). An error is raised if the metamethod lookup or index
 | 
						|
table lookup fails.
 | 
						|
 | 
						|
=head2 Indexing a cdata object
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item * B<Indexing a pointer/array>: a cdata pointer/array can be
 | 
						|
indexed by a cdata number or a Lua number. The element address is
 | 
						|
computed as the base address plus the number value multiplied by the
 | 
						|
element size in bytes. A read access loads the element value and
 | 
						|
converts it to a Lua object. A write access converts a Lua object to
 | 
						|
the element type and stores the converted value to the element. An
 | 
						|
error is raised if the element size is undefined or a write access to a
 | 
						|
constant element is attempted.
 | 
						|
 | 
						|
=item * B<Dereferencing a C<struct>/C<union> field>: a cdata
 | 
						|
C<struct>/C<union> or a pointer to a C<struct>/C<union> can be
 | 
						|
dereferenced by a string key, giving the field name. The field address
 | 
						|
is computed as the base address plus the relative offset of the field.
 | 
						|
A read access loads the field value and converts it to a Lua object. A
 | 
						|
write access converts a Lua object to the field type and stores the
 | 
						|
converted value to the field. An error is raised if a write access to a
 | 
						|
constant C<struct>/C<union> or a constant field is attempted. Scoped
 | 
						|
enum constants or static constants are treated like a constant field.
 | 
						|
 | 
						|
=item * B<Indexing a complex number>: a complex number can be indexed
 | 
						|
either by a cdata number or a Lua number with the values 0 or 1, or by
 | 
						|
the strings C<"re"> or C<"im">. A read access loads the real part
 | 
						|
(C<[0]>, C<.re>) or the imaginary part (C<[1]>, C<.im>) part of a
 | 
						|
complex number and converts it to a Lua number. The sub-parts of a
 | 
						|
complex number are immutable E<mdash> assigning to an index of a
 | 
						|
complex number raises an error. Accessing out-of-bound indexes returns
 | 
						|
unspecified results, but is guaranteed not to trigger memory access
 | 
						|
violations.
 | 
						|
 | 
						|
=item * B<Indexing a vector>: a vector is treated like an array for
 | 
						|
indexing purposes, except the vector elements are immutable E<mdash>
 | 
						|
assigning to an index of a vector raises an error.
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
A ctype object can be indexed with a string key, too. The only
 | 
						|
pre-defined operation is reading scoped constants of C<struct>/C<union>
 | 
						|
types. All other accesses defer to the corresponding metamethods or
 | 
						|
index tables (if any).
 | 
						|
 | 
						|
Note: since there's (deliberately) no address-of operator, a cdata
 | 
						|
object holding a value type is effectively immutable after
 | 
						|
initialization. The JIT compiler benefits from this fact when applying
 | 
						|
certain optimizations.
 | 
						|
 | 
						|
As a consequence, the I<elements> of complex numbers and vectors are
 | 
						|
immutable. But the elements of an aggregate holding these types I<may>
 | 
						|
be modified of course. I.e. you cannot assign to C<foo.c.im>, but you
 | 
						|
can assign a (newly created) complex number to C<foo.c>.
 | 
						|
 | 
						|
The JIT compiler implements strict aliasing rules: accesses to
 | 
						|
different types do B<not> alias, except for differences in signedness
 | 
						|
(this applies even to C<char> pointers, unlike C99). Type punning
 | 
						|
through unions is explicitly detected and allowed.
 | 
						|
 | 
						|
=head2 Calling a cdata object
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item * B<Constructor>: a ctype object can be called and used as a
 | 
						|
constructor. This is equivalent to C<ffi.new(ct, ...)>, unless a
 | 
						|
C<__new> metamethod is defined. The C<__new> metamethod is called with
 | 
						|
the ctype object plus any other arguments passed to the contructor.
 | 
						|
Note that you have to use C<ffi.new> inside of it, since calling
 | 
						|
C<ct(...)> would cause infinite recursion.
 | 
						|
 | 
						|
=item * B<C function call>: a cdata function or cdata function pointer
 | 
						|
can be called. The passed arguments are converted to the C types of the
 | 
						|
parameters given by the function declaration. Arguments passed to the
 | 
						|
variable argument part of vararg C function use special conversion
 | 
						|
rules. This C function is called and the return value (if any) is
 | 
						|
converted to a Lua object.
 | 
						|
 | 
						|
On Windows/x86 systems, C<__stdcall> functions are automatically
 | 
						|
detected and a function declared as C<__cdecl> (the default) is
 | 
						|
silently fixed up after the first call.
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
=head2 Arithmetic on cdata objects
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item * B<Pointer arithmetic>: a cdata pointer/array and a cdata number
 | 
						|
or a Lua number can be added or subtracted. The number must be on the
 | 
						|
right hand side for a subtraction. The result is a pointer of the same
 | 
						|
type with an address plus or minus the number value multiplied by the
 | 
						|
element size in bytes. An error is raised if the element size is
 | 
						|
undefined.
 | 
						|
 | 
						|
=item * B<Pointer difference>: two compatible cdata pointers/arrays can
 | 
						|
be subtracted. The result is the difference between their addresses,
 | 
						|
divided by the element size in bytes. An error is raised if the element
 | 
						|
size is undefined or zero.
 | 
						|
 | 
						|
=item * B<64 bit integer arithmetic>: the standard arithmetic operators
 | 
						|
(C<+ - * / % ^> and unary minus) can be applied to two cdata numbers,
 | 
						|
or a cdata number and a Lua number. If one of them is an C<uint64_t>,
 | 
						|
the other side is converted to an C<uint64_t> and an unsigned
 | 
						|
arithmetic operation is performed. Otherwise both sides are converted
 | 
						|
to an C<int64_t> and a signed arithmetic operation is performed. The
 | 
						|
result is a boxed 64 bit cdata object.
 | 
						|
 | 
						|
If one of the operands is an C<enum> and the other operand is a string,
 | 
						|
the string is converted to the value of a matching C<enum> constant
 | 
						|
before the above conversion.
 | 
						|
 | 
						|
These rules ensure that 64 bit integers are "sticky". Any expression
 | 
						|
involving at least one 64 bit integer operand results in another one.
 | 
						|
The undefined cases for the division, modulo and power operators return
 | 
						|
C<2LL ^ 63> or C<2ULL ^ 63>.
 | 
						|
 | 
						|
You'll have to explicitly convert a 64 bit integer to a Lua number
 | 
						|
(e.g. for regular floating-point calculations) with C<tonumber()>. But
 | 
						|
note this may incur a precision loss.
 | 
						|
 | 
						|
=item * B<64 bit bitwise operations>: the rules for 64 bit arithmetic
 | 
						|
operators apply analogously.
 | 
						|
 | 
						|
Unlike the other C<bit.*> operations, C<bit.tobit()> converts a cdata
 | 
						|
number via C<int64_t> to C<int32_t> and returns a Lua number.
 | 
						|
 | 
						|
For C<bit.band()>, C<bit.bor()> and C<bit.bxor()>, the conversion to
 | 
						|
C<int64_t> or C<uint64_t> applies to I<all> arguments, if I<any>
 | 
						|
argument is a cdata number.
 | 
						|
 | 
						|
For all other operations, only the first argument is used to determine
 | 
						|
the output type. This implies that a cdata number as a shift count for
 | 
						|
shifts and rotates is accepted, but that alone does I<not> cause a
 | 
						|
cdata number output.
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
=head2 Comparisons of cdata objects
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item * B<Pointer comparison>: two compatible cdata pointers/arrays can
 | 
						|
be compared. The result is the same as an unsigned comparison of their
 | 
						|
addresses. C<nil> is treated like a C<NULL> pointer, which is
 | 
						|
compatible with any other pointer type.
 | 
						|
 | 
						|
=item * B<64 bit integer comparison>: two cdata numbers, or a cdata
 | 
						|
number and a Lua number can be compared with each other. If one of them
 | 
						|
is an C<uint64_t>, the other side is converted to an C<uint64_t> and an
 | 
						|
unsigned comparison is performed. Otherwise both sides are converted to
 | 
						|
an C<int64_t> and a signed comparison is performed.
 | 
						|
 | 
						|
If one of the operands is an C<enum> and the other operand is a string,
 | 
						|
the string is converted to the value of a matching C<enum> constant
 | 
						|
before the above conversion.
 | 
						|
 | 
						|
=item * B<Comparisons for equality/inequality> never raise an error.
 | 
						|
Even incompatible pointers can be compared for equality by address. Any
 | 
						|
other incompatible comparison (also with non-cdata objects) treats the
 | 
						|
two sides as unequal.
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
=head2 cdata objects as table keys
 | 
						|
 | 
						|
Lua tables may be indexed by cdata objects, but this doesn't provide
 | 
						|
any useful semantics E<mdash> B<cdata objects are unsuitable as table
 | 
						|
keys!>
 | 
						|
 | 
						|
A cdata object is treated like any other garbage-collected object and
 | 
						|
is hashed and compared by its address for table indexing. Since there's
 | 
						|
no interning for cdata value types, the same value may be boxed in
 | 
						|
different cdata objects with different addresses. Thus C<t[1LL+1LL]>
 | 
						|
and C<t[2LL]> usually B<do not> point to the same hash slot and they
 | 
						|
certainly B<do not> point to the same hash slot as C<t[2]>.
 | 
						|
 | 
						|
It would seriously drive up implementation complexity and slow down the
 | 
						|
common case, if one were to add extra handling for by-value hashing and
 | 
						|
comparisons to Lua tables. Given the ubiquity of their use inside the
 | 
						|
VM, this is not acceptable.
 | 
						|
 | 
						|
There are three viable alternatives, if you really need to use cdata
 | 
						|
objects as keys:
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item * If you can get by with the precision of Lua numbers (52 bits),
 | 
						|
then use C<tonumber()> on a cdata number or combine multiple fields of
 | 
						|
a cdata aggregate to a Lua number. Then use the resulting Lua number as
 | 
						|
a key when indexing tables.
 | 
						|
 | 
						|
One obvious benefit: C<t[tonumber(2LL)]> B<does> point to the same slot
 | 
						|
as C<t[2]>.
 | 
						|
 | 
						|
=item * Otherwise use either C<tostring()> on 64 bit integers or
 | 
						|
complex numbers or combine multiple fields of a cdata aggregate to a
 | 
						|
Lua string (e.g. with C<ffi.string()>). Then use the resulting Lua
 | 
						|
string as a key when indexing tables.
 | 
						|
 | 
						|
=item * Create your own specialized hash table implementation using the
 | 
						|
C types provided by the FFI library, just like you would in C code.
 | 
						|
Ultimately this may give much better performance than the other
 | 
						|
alternatives or what a generic by-value hash table could possibly
 | 
						|
provide.
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
=head2 Parameterized Types
 | 
						|
 | 
						|
To facilitate some abstractions, the two functions C<ffi.typeof> and
 | 
						|
C<ffi.cdef> support parameterized types in C declarations. Note: none
 | 
						|
of the other API functions taking a cdecl allow this.
 | 
						|
 | 
						|
Any place you can write a B<C<typedef> name>, an B<identifier> or a
 | 
						|
B<number> in a declaration, you can write C<$> (the dollar sign)
 | 
						|
instead. These placeholders are replaced in order of appearance with
 | 
						|
the arguments following the cdecl string:
 | 
						|
 | 
						|
 -- Declare a struct with a parameterized field type and name:
 | 
						|
 ffi.cdef([[
 | 
						|
 typedef struct { $ $; } foo_t;
 | 
						|
 ]], type1, name1)
 | 
						|
 
 | 
						|
 -- Anonymous struct with dynamic names:
 | 
						|
 local bar_t = ffi.typeof("struct { int $, $; }", name1, name2)
 | 
						|
 -- Derived pointer type:
 | 
						|
 local bar_ptr_t = ffi.typeof("$ *", bar_t)
 | 
						|
 
 | 
						|
 -- Parameterized dimensions work even where a VLA won't work:
 | 
						|
 local matrix_t = ffi.typeof("uint8_t[$][$]", width, height)
 | 
						|
 | 
						|
Caveat: this is I<not> simple text substitution! A passed ctype or
 | 
						|
cdata object is treated like the underlying type, a passed string is
 | 
						|
considered an identifier and a number is considered a number. You must
 | 
						|
not mix this up: e.g. passing C<"int"> as a string doesn't work in
 | 
						|
place of a type, you'd need to use C<ffi.typeof("int")> instead.
 | 
						|
 | 
						|
The main use for parameterized types are libraries implementing
 | 
						|
abstract data types (example), similar to what can be achieved with C++
 | 
						|
template metaprogramming. Another use case are derived types of
 | 
						|
anonymous structs, which avoids pollution of the global struct
 | 
						|
namespace.
 | 
						|
 | 
						|
Please note that parameterized types are a nice tool and indispensable
 | 
						|
for certain use cases. But you'll want to use them sparingly in regular
 | 
						|
code, e.g. when all types are actually fixed.
 | 
						|
 | 
						|
=head2 Garbage Collection of cdata Objects
 | 
						|
 | 
						|
All explicitly (C<ffi.new()>, C<ffi.cast()> etc.) or implicitly
 | 
						|
(accessors) created cdata objects are garbage collected. You need to
 | 
						|
ensure to retain valid references to cdata objects somewhere on a Lua
 | 
						|
stack, an upvalue or in a Lua table while they are still in use. Once
 | 
						|
the last reference to a cdata object is gone, the garbage collector
 | 
						|
will automatically free the memory used by it (at the end of the next
 | 
						|
GC cycle).
 | 
						|
 | 
						|
Please note that pointers themselves are cdata objects, however they
 | 
						|
are B<not> followed by the garbage collector. So e.g. if you assign a
 | 
						|
cdata array to a pointer, you must keep the cdata object holding the
 | 
						|
array alive as long as the pointer is still in use:
 | 
						|
 | 
						|
 ffi.cdef[[
 | 
						|
 typedef struct { int *a; } foo_t;
 | 
						|
 ]]
 | 
						|
 
 | 
						|
 local s = ffi.new("foo_t", ffi.new("int[10]")) -- WRONG!
 | 
						|
 
 | 
						|
 local a = ffi.new("int[10]") -- OK
 | 
						|
 local s = ffi.new("foo_t", a)
 | 
						|
 -- Now do something with 's', but keep 'a' alive until you're done.
 | 
						|
 | 
						|
Similar rules apply for Lua strings which are implicitly converted to
 | 
						|
C<"const char *">: the string object itself must be referenced
 | 
						|
somewhere or it'll be garbage collected eventually. The pointer will
 | 
						|
then point to stale data, which may have already been overwritten. Note
 | 
						|
that I<string literals> are automatically kept alive as long as the
 | 
						|
function containing it (actually its prototype) is not garbage
 | 
						|
collected.
 | 
						|
 | 
						|
Objects which are passed as an argument to an external C function are
 | 
						|
kept alive until the call returns. So it's generally safe to create
 | 
						|
temporary cdata objects in argument lists. This is a common idiom for
 | 
						|
passing specific C types to vararg functions.
 | 
						|
 | 
						|
Memory areas returned by C functions (e.g. from C<malloc()>) must be
 | 
						|
manually managed, of course (or use C<ffi.gc()>). Pointers to cdata
 | 
						|
objects are indistinguishable from pointers returned by C functions
 | 
						|
(which is one of the reasons why the GC cannot follow them).
 | 
						|
 | 
						|
=head2 Callbacks
 | 
						|
 | 
						|
The LuaJIT FFI automatically generates special callback functions
 | 
						|
whenever a Lua function is converted to a C function pointer. This
 | 
						|
associates the generated callback function pointer with the C type of
 | 
						|
the function pointer and the Lua function object (closure).
 | 
						|
 | 
						|
This can happen implicitly due to the usual conversions, e.g. when
 | 
						|
passing a Lua function to a function pointer argument. Or you can use
 | 
						|
C<ffi.cast()> to explicitly cast a Lua function to a C function
 | 
						|
pointer.
 | 
						|
 | 
						|
Currently only certain C function types can be used as callback
 | 
						|
functions. Neither C vararg functions nor functions with pass-by-value
 | 
						|
aggregate argument or result types are supported. There are no
 | 
						|
restrictions for the kind of Lua functions that can be called from the
 | 
						|
callback E<mdash> no checks for the proper number of arguments are
 | 
						|
made. The return value of the Lua function will be converted to the
 | 
						|
result type and an error will be thrown for invalid conversions.
 | 
						|
 | 
						|
It's allowed to throw errors across a callback invocation, but it's not
 | 
						|
advisable in general. Do this only if you know the C function, that
 | 
						|
called the callback, copes with the forced stack unwinding and doesn't
 | 
						|
leak resources.
 | 
						|
 | 
						|
One thing that's not allowed, is to let an FFI call into a C function
 | 
						|
get JIT-compiled, which in turn calls a callback, calling into Lua
 | 
						|
again. Usually this attempt is caught by the interpreter first and the
 | 
						|
C function is blacklisted for compilation.
 | 
						|
 | 
						|
However, this heuristic may fail under specific circumstances: e.g. a
 | 
						|
message polling function might not run Lua callbacks right away and the
 | 
						|
call gets JIT-compiled. If it later happens to call back into Lua (e.g.
 | 
						|
a rarely invoked error callback), you'll get a VM PANIC with the
 | 
						|
message C<"bad callback">. Then you'll need to manually turn off
 | 
						|
JIT-compilation with C<jit.off()> for the surrounding Lua function that
 | 
						|
invokes such a message polling function (or similar).
 | 
						|
 | 
						|
=head2 Callback resource handling
 | 
						|
 | 
						|
Callbacks take up resources E<mdash> you can only have a limited number
 | 
						|
of them at the same time (500 - 1000, depending on the architecture).
 | 
						|
The associated Lua functions are anchored to prevent garbage
 | 
						|
collection, too.
 | 
						|
 | 
						|
B<Callbacks due to implicit conversions are permanent!> There is no way
 | 
						|
to guess their lifetime, since the C side might store the function
 | 
						|
pointer for later use (typical for GUI toolkits). The associated
 | 
						|
resources cannot be reclaimed until termination:
 | 
						|
 | 
						|
 ffi.cdef[[
 | 
						|
 typedef int (__stdcall *WNDENUMPROC)(void *hwnd, intptr_t l);
 | 
						|
 int EnumWindows(WNDENUMPROC func, intptr_t l);
 | 
						|
 ]]
 | 
						|
 
 | 
						|
 -- Implicit conversion to a callback via function pointer argument.
 | 
						|
 local count = 0
 | 
						|
 ffi.C.EnumWindows(function(hwnd, l)
 | 
						|
   count = count + 1
 | 
						|
   return true
 | 
						|
 end, 0)
 | 
						|
 -- The callback is permanent and its resources cannot be reclaimed!
 | 
						|
 -- Ok, so this may not be a problem, if you do this only once.
 | 
						|
 | 
						|
Note: this example shows that you I<must> properly declare C<__stdcall>
 | 
						|
callbacks on Windows/x86 systems. The calling convention cannot be
 | 
						|
automatically detected, unlike for C<__stdcall> calls I<to> Windows
 | 
						|
functions.
 | 
						|
 | 
						|
For some use cases it's necessary to free up the resources or to
 | 
						|
dynamically redirect callbacks. Use an explicit cast to a C function
 | 
						|
pointer and keep the resulting cdata object. Then use the C<cb:free()>
 | 
						|
or C<cb:set()> methods on the cdata object:
 | 
						|
 | 
						|
 -- Explicitly convert to a callback via cast.
 | 
						|
 local count = 0
 | 
						|
 local cb = ffi.cast("WNDENUMPROC", function(hwnd, l)
 | 
						|
   count = count + 1
 | 
						|
   return true
 | 
						|
 end)
 | 
						|
 
 | 
						|
 -- Pass it to a C function.
 | 
						|
 ffi.C.EnumWindows(cb, 0)
 | 
						|
 -- EnumWindows doesn't need the callback after it returns, so free it.
 | 
						|
 
 | 
						|
 cb:free()
 | 
						|
 -- The callback function pointer is no longer valid and its resources
 | 
						|
 -- will be reclaimed. The created Lua closure will be garbage collected.
 | 
						|
 | 
						|
=head2 Callback performance
 | 
						|
 | 
						|
B<Callbacks are slow!> First, the C to Lua transition itself has an
 | 
						|
unavoidable cost, similar to a C<lua_call()> or C<lua_pcall()>.
 | 
						|
Argument and result marshalling add to that cost. And finally, neither
 | 
						|
the C compiler nor LuaJIT can inline or optimize across the language
 | 
						|
barrier and hoist repeated computations out of a callback function.
 | 
						|
 | 
						|
Do not use callbacks for performance-sensitive work: e.g. consider a
 | 
						|
numerical integration routine which takes a user-defined function to
 | 
						|
integrate over. It's a bad idea to call a user-defined Lua function
 | 
						|
from C code millions of times. The callback overhead will be absolutely
 | 
						|
detrimental for performance.
 | 
						|
 | 
						|
It's considerably faster to write the numerical integration routine
 | 
						|
itself in Lua E<mdash> the JIT compiler will be able to inline the
 | 
						|
user-defined function and optimize it together with its calling
 | 
						|
context, with very competitive performance.
 | 
						|
 | 
						|
As a general guideline: B<use callbacks only when you must>, because of
 | 
						|
existing C APIs. E.g. callback performance is irrelevant for a GUI
 | 
						|
application, which waits for user input most of the time, anyway.
 | 
						|
 | 
						|
For new designs B<avoid push-style APIs>: a C function repeatedly
 | 
						|
calling a callback for each result. Instead B<use pull-style APIs>:
 | 
						|
call a C function repeatedly to get a new result. Calls from Lua to C
 | 
						|
via the FFI are much faster than the other way round. Most
 | 
						|
well-designed libraries already use pull-style APIs (read/write,
 | 
						|
get/put).
 | 
						|
 | 
						|
=head2 C Library Namespaces
 | 
						|
 | 
						|
A C library namespace is a special kind of object which allows access
 | 
						|
to the symbols contained in shared libraries or the default symbol
 | 
						|
namespace. The default C<ffi.C> namespace is automatically created when
 | 
						|
the FFI library is loaded. C library namespaces for specific shared
 | 
						|
libraries may be created with the C<ffi.load()> API function.
 | 
						|
 | 
						|
Indexing a C library namespace object with a symbol name (a Lua string)
 | 
						|
automatically binds it to the library. First the symbol type is
 | 
						|
resolved E<mdash> it must have been declared with C<ffi.cdef>. Then the
 | 
						|
symbol address is resolved by searching for the symbol name in the
 | 
						|
associated shared libraries or the default symbol namespace. Finally,
 | 
						|
the resulting binding between the symbol name, the symbol type and its
 | 
						|
address is cached. Missing symbol declarations or nonexistent symbol
 | 
						|
names cause an error.
 | 
						|
 | 
						|
This is what happens on a B<read access> for the different kinds of
 | 
						|
symbols:
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item * External functions: a cdata object with the type of the
 | 
						|
function and its address is returned.
 | 
						|
 | 
						|
=item * External variables: the symbol address is dereferenced and the
 | 
						|
loaded value is converted to a Lua object and returned.
 | 
						|
 | 
						|
=item * Constant values (C<static const> or C<enum> constants): the
 | 
						|
constant is converted to a Lua object and returned.
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
This is what happens on a B<write access>:
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item * External variables: the value to be written is converted to the
 | 
						|
C type of the variable and then stored at the symbol address.
 | 
						|
 | 
						|
=item * Writing to constant variables or to any other symbol type
 | 
						|
causes an error, like any other attempted write to a constant location.
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
C library namespaces themselves are garbage collected objects. If the
 | 
						|
last reference to the namespace object is gone, the garbage collector
 | 
						|
will eventually release the shared library reference and remove all
 | 
						|
memory associated with the namespace. Since this may trigger the
 | 
						|
removal of the shared library from the memory of the running process,
 | 
						|
it's generally I<not safe> to use function cdata objects obtained from
 | 
						|
a library if the namespace object may be unreferenced.
 | 
						|
 | 
						|
Performance notice: the JIT compiler specializes to the identity of
 | 
						|
namespace objects and to the strings used to index it. This effectively
 | 
						|
turns function cdata objects into constants. It's not useful and
 | 
						|
actually counter-productive to explicitly cache these function objects,
 | 
						|
e.g. C<local strlen = ffi.C.strlen>. OTOH it I<is> useful to cache the
 | 
						|
namespace itself, e.g. C<local C = ffi.C>.
 | 
						|
 | 
						|
=head2 No Hand-holding!
 | 
						|
 | 
						|
The FFI library has been designed as B<a low-level library>. The goal
 | 
						|
is to interface with C code and C data types with a minimum of
 | 
						|
overhead. This means B<you can do anything you can do from C>: access
 | 
						|
all memory, overwrite anything in memory, call machine code at any
 | 
						|
memory address and so on.
 | 
						|
 | 
						|
The FFI library provides B<no memory safety>, unlike regular Lua code.
 | 
						|
It will happily allow you to dereference a C<NULL> pointer, to access
 | 
						|
arrays out of bounds or to misdeclare C functions. If you make a
 | 
						|
mistake, your application might crash, just like equivalent C code
 | 
						|
would.
 | 
						|
 | 
						|
This behavior is inevitable, since the goal is to provide full
 | 
						|
interoperability with C code. Adding extra safety measures, like bounds
 | 
						|
checks, would be futile. There's no way to detect misdeclarations of C
 | 
						|
functions, since shared libraries only provide symbol names, but no
 | 
						|
type information. Likewise there's no way to infer the valid range of
 | 
						|
indexes for a returned pointer.
 | 
						|
 | 
						|
Again: the FFI library is a low-level library. This implies it needs to
 | 
						|
be used with care, but it's flexibility and performance often outweigh
 | 
						|
this concern. If you're a C or C++ developer, it'll be easy to apply
 | 
						|
your existing knowledge. OTOH writing code for the FFI library is not
 | 
						|
for the faint of heart and probably shouldn't be the first exercise for
 | 
						|
someone with little experience in Lua, C or C++.
 | 
						|
 | 
						|
As a corollary of the above, the FFI library is B<not safe for use by
 | 
						|
untrusted Lua code>. If you're sandboxing untrusted Lua code, you
 | 
						|
definitely don't want to give this code access to the FFI library or to
 | 
						|
I<any> cdata object (except 64 bit integers or complex numbers). Any
 | 
						|
properly engineered Lua sandbox needs to provide safety wrappers for
 | 
						|
many of the standard Lua library functions E<mdash> similar wrappers
 | 
						|
need to be written for high-level operations on FFI data types, too.
 | 
						|
 | 
						|
=head2 Current Status
 | 
						|
 | 
						|
The initial release of the FFI library has some limitations and is
 | 
						|
missing some features. Most of these will be fixed in future releases.
 | 
						|
 | 
						|
C language support is currently incomplete:
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item * C declarations are not passed through a C pre-processor, yet.
 | 
						|
 | 
						|
=item * The C parser is able to evaluate most constant expressions
 | 
						|
commonly found in C header files. However it doesn't handle the full
 | 
						|
range of C expression semantics and may fail for some obscure
 | 
						|
constructs.
 | 
						|
 | 
						|
=item * C<static const> declarations only work for integer types up to
 | 
						|
32 bits. Neither declaring string constants nor floating-point
 | 
						|
constants is supported.
 | 
						|
 | 
						|
=item * Packed C<struct> bitfields that cross container boundaries are
 | 
						|
not implemented.
 | 
						|
 | 
						|
=item * Native vector types may be defined with the GCC C<mode> or
 | 
						|
C<vector_size> attribute. But no operations other than loading, storing
 | 
						|
and initializing them are supported, yet.
 | 
						|
 | 
						|
=item * The C<volatile> type qualifier is currently ignored by compiled
 | 
						|
code.
 | 
						|
 | 
						|
=item * C<ffi.cdef> silently ignores most re-declarations. Note: avoid
 | 
						|
re-declarations which do not conform to C99. The implementation will
 | 
						|
eventually be changed to perform strict checks.
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
The JIT compiler already handles a large subset of all FFI operations.
 | 
						|
It automatically falls back to the interpreter for unimplemented
 | 
						|
operations (you can check for this with the C<-jv> command line
 | 
						|
option). The following operations are currently not compiled and may
 | 
						|
exhibit suboptimal performance, especially when used in inner loops:
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item * Vector operations.
 | 
						|
 | 
						|
=item * Table initializers.
 | 
						|
 | 
						|
=item * Initialization of nested C<struct>/C<union> types.
 | 
						|
 | 
						|
=item * Non-default initialization of VLA/VLS or large C types (E<gt>
 | 
						|
128 bytes or E<gt> 16 array elements.
 | 
						|
 | 
						|
=item * Bitfield initializations.
 | 
						|
 | 
						|
=item * Pointer differences for element sizes that are not a power of
 | 
						|
two.
 | 
						|
 | 
						|
=item * Calls to C functions with aggregates passed or returned by
 | 
						|
value.
 | 
						|
 | 
						|
=item * Calls to ctype metamethods which are not plain functions.
 | 
						|
 | 
						|
=item * ctype C<__newindex> tables and non-string lookups in ctype
 | 
						|
C<__index> tables.
 | 
						|
 | 
						|
=item * C<tostring()> for cdata types.
 | 
						|
 | 
						|
=item * Calls to C<ffi.cdef()>, C<ffi.load()> and C<ffi.metatype()>.
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
Other missing features:
 | 
						|
 | 
						|
=over
 | 
						|
 | 
						|
=item * Arithmetic for C<complex> numbers.
 | 
						|
 | 
						|
=item * Passing structs by value to vararg C functions.
 | 
						|
 | 
						|
=item * C++ exception interoperability does not extend to C functions
 | 
						|
called via the FFI, if the call is compiled.
 | 
						|
 | 
						|
=back
 | 
						|
 | 
						|
----
 | 
						|
 | 
						|
Copyright E<copy> 2005-2017 Mike Pall E<middot> Contact
 | 
						|
 | 
						|
=cut
 | 
						|
 | 
						|
#Pod::HTML2Pod conversion notes:
 | 
						|
#From file ext_ffi_semantics.html
 | 
						|
# 53732 bytes of input
 | 
						|
#Mon May 14 13:19:16 2018 agentzh
 | 
						|
# No a_name switch not specified, so will not try to render <a name='...'>
 | 
						|
# No a_href switch not specified, so will not try to render <a href='...'>
 |