| # External blocks |
| |
| > **<sup>Syntax</sup>**\ |
| > _ExternBlock_ :\ |
| > `unsafe`<sup>?</sup> `extern` [_Abi_]<sup>?</sup> `{`\ |
| > [_InnerAttribute_]<sup>\*</sup>\ |
| > _ExternalItem_<sup>\*</sup>\ |
| > `}` |
| > |
| > _ExternalItem_ :\ |
| > [_OuterAttribute_]<sup>\*</sup> (\ |
| > [_MacroInvocationSemi_]\ |
| > | ( [_Visibility_]<sup>?</sup> ( [_StaticItem_] | [_Function_] ) )\ |
| > ) |
| |
| External blocks provide _declarations_ of items that are not _defined_ in the |
| current crate and are the basis of Rust's foreign function interface. These are |
| akin to unchecked imports. |
| |
| Two kinds of item _declarations_ are allowed in external blocks: [functions] and |
| [statics]. Calling functions or accessing statics that are declared in external |
| blocks is only allowed in an `unsafe` context. |
| |
| The `unsafe` keyword is syntactically allowed to appear before the `extern` |
| keyword, but it is rejected at a semantic level. This allows macros to consume |
| the syntax and make use of the `unsafe` keyword, before removing it from the |
| token stream. |
| |
| ## Functions |
| |
| Functions within external blocks are declared in the same way as other Rust |
| functions, with the exception that they must not have a body and are instead |
| terminated by a semicolon. Patterns are not allowed in parameters, only |
| [IDENTIFIER] or `_` may be used. Function qualifiers (`const`, `async`, |
| `unsafe`, and `extern`) are not allowed. |
| |
| Functions within external blocks may be called by Rust code, just like |
| functions defined in Rust. The Rust compiler automatically translates between |
| the Rust ABI and the foreign ABI. |
| |
| A function declared in an extern block is implicitly `unsafe`. When coerced to |
| a function pointer, a function declared in an extern block has type `unsafe |
| extern "abi" for<'l1, ..., 'lm> fn(A1, ..., An) -> R`, where `'l1`, ... `'lm` |
| are its lifetime parameters, `A1`, ..., `An` are the declared types of its |
| parameters and `R` is the declared return type. |
| |
| ## Statics |
| |
| Statics within external blocks are declared in the same way as [statics] outside of external blocks, |
| except that they do not have an expression initializing their value. |
| It is `unsafe` to access a static item declared in an extern block, whether or |
| not it's mutable, because there is nothing guaranteeing that the bit pattern at the static's |
| memory is valid for the type it is declared with, since some arbitrary (e.g. C) code is in charge |
| of initializing the static. |
| |
| Extern statics can be either immutable or mutable just like [statics] outside of external blocks. |
| An immutable static *must* be initialized before any Rust code is executed. It is not enough for |
| the static to be initialized before Rust code reads from it. |
| |
| ## ABI |
| |
| By default external blocks assume that the library they are calling uses the |
| standard C ABI on the specific platform. Other ABIs may be specified using an |
| `abi` string, as shown here: |
| |
| ```rust |
| // Interface to the Windows API |
| extern "stdcall" { } |
| ``` |
| |
| There are three ABI strings which are cross-platform, and which all compilers |
| are guaranteed to support: |
| |
| * `extern "Rust"` -- The default ABI when you write a normal `fn foo()` in any |
| Rust code. |
| * `extern "C"` -- This is the same as `extern fn foo()`; whatever the default |
| your C compiler supports. |
| * `extern "system"` -- Usually the same as `extern "C"`, except on Win32, in |
| which case it's `"stdcall"`, or what you should use to link to the Windows |
| API itself |
| |
| There are also some platform-specific ABI strings: |
| |
| * `extern "cdecl"` -- The default for x86\_32 C code. |
| * `extern "stdcall"` -- The default for the Win32 API on x86\_32. |
| * `extern "win64"` -- The default for C code on x86\_64 Windows. |
| * `extern "sysv64"` -- The default for C code on non-Windows x86\_64. |
| * `extern "aapcs"` -- The default for ARM. |
| * `extern "fastcall"` -- The `fastcall` ABI -- corresponds to MSVC's |
| `__fastcall` and GCC and clang's `__attribute__((fastcall))` |
| * `extern "vectorcall"` -- The `vectorcall` ABI -- corresponds to MSVC's |
| `__vectorcall` and clang's `__attribute__((vectorcall))` |
| |
| ## Variadic functions |
| |
| Functions within external blocks may be variadic by specifying `...` as the |
| last argument. There must be at least one parameter before the variadic |
| parameter. The variadic parameter may optionally be specified with an |
| identifier. |
| |
| ```rust |
| extern "C" { |
| fn foo(x: i32, ...); |
| fn with_name(format: *const u8, args: ...); |
| } |
| ``` |
| |
| ## Attributes on extern blocks |
| |
| The following [attributes] control the behavior of external blocks. |
| |
| ### The `link` attribute |
| |
| The *`link` attribute* specifies the name of a native library that the |
| compiler should link with for the items within an `extern` block. It uses the |
| [_MetaListNameValueStr_] syntax to specify its inputs. The `name` key is the |
| name of the native library to link. The `kind` key is an optional value which |
| specifies the kind of library with the following possible values: |
| |
| - `dylib` — Indicates a dynamic library. This is the default if `kind` is not |
| specified. |
| - `static` — Indicates a static library. |
| - `framework` — Indicates a macOS framework. This is only valid for macOS |
| targets. |
| |
| The `name` key must be included if `kind` is specified. |
| |
| The optional `modifiers` argument is a way to specify linking modifiers for the |
| library to link. |
| Modifiers are specified as a comma-delimited string with each modifier prefixed |
| with either a `+` or `-` to indicate that the modifier is enabled or disabled, |
| respectively. |
| Specifying multiple `modifiers` arguments in a single `link` attribute, |
| or multiple identical modifiers in the same `modifiers` argument is not currently supported. \ |
| Example: `#[link(name = "mylib", kind = "static", modifiers = "+whole-archive")`. |
| |
| The `wasm_import_module` key may be used to specify the [WebAssembly module] |
| name for the items within an `extern` block when importing symbols from the |
| host environment. The default module name is `env` if `wasm_import_module` is |
| not specified. |
| |
| <!-- ignore: requires extern linking --> |
| ```rust,ignore |
| #[link(name = "crypto")] |
| extern { |
| // … |
| } |
| |
| #[link(name = "CoreFoundation", kind = "framework")] |
| extern { |
| // … |
| } |
| |
| #[link(wasm_import_module = "foo")] |
| extern { |
| // … |
| } |
| ``` |
| |
| It is valid to add the `link` attribute on an empty extern block. You can use |
| this to satisfy the linking requirements of extern blocks elsewhere in your |
| code (including upstream crates) instead of adding the attribute to each extern |
| block. |
| |
| #### Linking modifiers: `bundle` |
| |
| This modifier is only compatible with the `static` linking kind. |
| Using any other kind will result in a compiler error. |
| |
| When building a rlib or staticlib `+bundle` means that all object files from the native static |
| library will be added to the rlib or staticlib archive, and then used from it during linking of |
| the final binary. |
| |
| When building a rlib `-bundle` means that the native static library is registered as a dependency |
| of that rlib "by name", and object files from it are included only during linking of the final |
| binary, the file search by that name is also performed during final linking. \ |
| When building a staticlib `-bundle` means that the native static library is simply not included |
| into the archive and some higher level build system will need to add it later during linking of |
| the final binary. |
| |
| This modifier has no effect when building other targets like executables or dynamic libraries. |
| |
| The default for this modifier is `+bundle`. |
| |
| More implementation details about this modifier can be found in |
| [`bundle` documentation for rustc]. |
| |
| #### Linking modifiers: `whole-archive` |
| |
| This modifier is only compatible with the `static` linking kind. |
| Using any other kind will result in a compiler error. |
| |
| `+whole-archive` means that the static library is linked as a whole archive |
| without throwing any object files away. |
| |
| The default for this modifier is `-whole-archive`. |
| |
| More implementation details about this modifier can be found in |
| [`whole-archive` documentation for rustc]. |
| |
| ### The `link_name` attribute |
| |
| The `link_name` attribute may be specified on declarations inside an `extern` |
| block to indicate the symbol to import for the given function or static. It |
| uses the [_MetaNameValueStr_] syntax to specify the name of the symbol. |
| |
| ```rust |
| extern { |
| #[link_name = "actual_symbol_name"] |
| fn name_in_rust(); |
| } |
| ``` |
| |
| ### Attributes on function parameters |
| |
| Attributes on extern function parameters follow the same rules and |
| restrictions as [regular function parameters]. |
| |
| [IDENTIFIER]: ../identifiers.md |
| [WebAssembly module]: https://webassembly.github.io/spec/core/syntax/modules.html |
| [functions]: functions.md |
| [statics]: static-items.md |
| [_Abi_]: functions.md |
| [_Function_]: functions.md |
| [_InnerAttribute_]: ../attributes.md |
| [_MacroInvocationSemi_]: ../macros.md#macro-invocation |
| [_MetaListNameValueStr_]: ../attributes.md#meta-item-attribute-syntax |
| [_MetaNameValueStr_]: ../attributes.md#meta-item-attribute-syntax |
| [_OuterAttribute_]: ../attributes.md |
| [_StaticItem_]: static-items.md |
| [_Visibility_]: ../visibility-and-privacy.md |
| [attributes]: ../attributes.md |
| [regular function parameters]: functions.md#attributes-on-function-parameters |
| [`bundle` documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-bundle |
| [`whole-archive` documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-whole-archive |