21. FFI¶
Legality Rules
21:1 Foreign Function Interface or FFI employs ABI, attributes, external blocks, external functions, linkage, and type layout to interface a Rust program with foreign code.
21:2 The following attributes affect FFI:
21:3 Attribute
export_name
.21:5 Attribute
link_section
21.1. ABI¶
Syntax
AbiSpecification
::= externAbiKind
?AbiKind
::=RawStringLiteral
|StringLiteral
Legality Rules
21.1:1 Application Binary Interface or ABI is a set of conventions that dictate how data and computation cross language boundaries.
21.1:2 The ABI kind indicates the ABI of a construct.
21.1:3 The following ABIs are supported:
21.1:4
extern "C"
- The default ABI of C code, referred to as extern C ABI.21.1:5
extern "C-unwind"
- The same asextern "C"
with the addition that unwinding across FFI is permitted.21.1:6
extern "Rust"
- The default ABI of a Rust program, referred to as Rust ABI.21.1:7
extern "system"
- The operating system-dependent ABI, referred to as external system ABI.21.1:8
extern "system-unwind"
- The same asextern "system"
with the addition that unwinding across FFI is permitted.
21.1:9 A function without an explicit ABI has implicit Rust ABI, unless it appears within an external block.
21.1:10 A function with an ABI but without a specified ABI kind has implicit extern C ABI.
Implementation Permissions
21.1:11 A tool is allowed to specify additional ABIs. These ABIs may include, but may not be limited to, the following:
21.1:12
extern "aapcs"
- The ARM ABI.21.1:14
extern "fastcall"
- Thefastcall
ABI that corresponds to MSVC’s__fastcall
and GCC and clang’s__attribute__((fastcall))
.21.1:15
extern "stdcall"
- The x86_32 ABI of the Win32 API.21.1:16
extern "sysv64"
- The x86_64 non-Windows ABI of C code.21.1:17
extern "vectorcall"
- Thevectorcall
ABI that corresponds to MSVC’s__vectorcall
and clang’s__attribute__((vectorcall))
.
Undefined Behavior
21.1:19
It is undefined behavior when a foreign exception crosses a
foreign function interface boundary with an ABI that does not end in
-unwind
.
Examples
extern
extern "C"
21.2. External Blocks¶
Syntax
ExternalBlock
::= unsafe? externAbiKind
? {InnerAttributeOrDoc
*ExternItem
* }ExternItem
::=OuterAttributeOrDoc
* (ExternalItemWithVisibility
|TerminatedMacroInvocation
)ExternalItemWithVisibility
::=VisibilityModifier
? (FunctionDeclaration
|StaticDeclaration
)
Legality Rules
21.2:1 An external block is a construct that provides the declarations of foreign functions as unchecked imports.
21.2:2 The ABI of an external block is determined as follows:
21.2:3 If the external block specifies an
AbiKind
, then the ABI is the specifiedAbiKind
.21.2:4 Otherwise the ABI is the extern C ABI.
21.2:5
The unsafe
keyword of an external block is rejected, but may
still be consumed by macros.
Examples
extern "C" {
static MAX_LENGTH: size_t;
fn compress
(input: *const u8,
input_length: size_t,
compressed: *mut u8,
compressed_length: *mut size_t) -> c_int;
fn log(msg: *const c_char, ...);
}
21.3. External Functions¶
Legality Rules
21.3:1 An external function is an unchecked import of a foreign function.
21.3:2 An external function shall be invoked from an unsafe context.
21.3:3
An external function shall not specify a FunctionQualifierList
.
21.3:4 An external function inherits the ABI of its enclosing external block.
21.3:5
An external function shall not specify a GenericParameterList
containing constant parameters or type parameters.
21.3:6
An external function shall not specify a FunctionBody
.
21.3:7 An external function shall not specify patterns other than identifier patterns and underscore patterns.
21.3:8
Only the last parameter FunctionParameter
of an external function may
specify a FunctionParameterVariadicPart
.
21.4. External Statics¶
Legality Rules
21.4:1 An external static is an import of a foreign variable.
21.4:2 An external static inherits the ABI of its enclosing external block.
21.4:3 An external static shall be referenced from an unsafe context.
21.4:4 An external static shall not specify a static initializer.
Dynamic Semantics
21.4:5 An immutable external static shall be initialized before Rust code is executed.