|
|
@ -1,6 +1,6 @@
|
|
|
|
# Foreign Function Interface
|
|
|
|
# Foreign Function Interface
|
|
|
|
|
|
|
|
|
|
|
|
# Introduction
|
|
|
|
## Introduction
|
|
|
|
|
|
|
|
|
|
|
|
This guide will use the [snappy](https://github.com/google/snappy)
|
|
|
|
This guide will use the [snappy](https://github.com/google/snappy)
|
|
|
|
compression/decompression library as an introduction to writing bindings for
|
|
|
|
compression/decompression library as an introduction to writing bindings for
|
|
|
@ -85,7 +85,7 @@ extern {
|
|
|
|
# fn main() {}
|
|
|
|
# fn main() {}
|
|
|
|
```
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
# Creating a safe interface
|
|
|
|
## Creating a safe interface
|
|
|
|
|
|
|
|
|
|
|
|
The raw C API needs to be wrapped to provide memory safety and make use of higher-level concepts
|
|
|
|
The raw C API needs to be wrapped to provide memory safety and make use of higher-level concepts
|
|
|
|
like vectors. A library can choose to expose only the safe, high-level interface and hide the unsafe
|
|
|
|
like vectors. A library can choose to expose only the safe, high-level interface and hide the unsafe
|
|
|
@ -234,7 +234,7 @@ mod tests {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
# Destructors
|
|
|
|
## Destructors
|
|
|
|
|
|
|
|
|
|
|
|
Foreign libraries often hand off ownership of resources to the calling code.
|
|
|
|
Foreign libraries often hand off ownership of resources to the calling code.
|
|
|
|
When this occurs, we must use Rust's destructors to provide safety and guarantee
|
|
|
|
When this occurs, we must use Rust's destructors to provide safety and guarantee
|
|
|
@ -242,7 +242,7 @@ the release of these resources (especially in the case of panic).
|
|
|
|
|
|
|
|
|
|
|
|
For more about destructors, see the [Drop trait](../std/ops/trait.Drop.html).
|
|
|
|
For more about destructors, see the [Drop trait](../std/ops/trait.Drop.html).
|
|
|
|
|
|
|
|
|
|
|
|
# Callbacks from C code to Rust functions
|
|
|
|
## Callbacks from C code to Rust functions
|
|
|
|
|
|
|
|
|
|
|
|
Some external libraries require the usage of callbacks to report back their
|
|
|
|
Some external libraries require the usage of callbacks to report back their
|
|
|
|
current state or intermediate data to the caller.
|
|
|
|
current state or intermediate data to the caller.
|
|
|
@ -295,7 +295,6 @@ void trigger_callback() {
|
|
|
|
In this example Rust's `main()` will call `trigger_callback()` in C,
|
|
|
|
In this example Rust's `main()` will call `trigger_callback()` in C,
|
|
|
|
which would, in turn, call back to `callback()` in Rust.
|
|
|
|
which would, in turn, call back to `callback()` in Rust.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Targeting callbacks to Rust objects
|
|
|
|
## Targeting callbacks to Rust objects
|
|
|
|
|
|
|
|
|
|
|
|
The former example showed how a global function can be called from C code.
|
|
|
|
The former example showed how a global function can be called from C code.
|
|
|
@ -384,7 +383,7 @@ This can be achieved by unregistering the callback in the object's
|
|
|
|
destructor and designing the library in a way that guarantees that no
|
|
|
|
destructor and designing the library in a way that guarantees that no
|
|
|
|
callback will be performed after deregistration.
|
|
|
|
callback will be performed after deregistration.
|
|
|
|
|
|
|
|
|
|
|
|
# Linking
|
|
|
|
## Linking
|
|
|
|
|
|
|
|
|
|
|
|
The `link` attribute on `extern` blocks provides the basic building block for
|
|
|
|
The `link` attribute on `extern` blocks provides the basic building block for
|
|
|
|
instructing rustc how it will link to native libraries. There are two accepted
|
|
|
|
instructing rustc how it will link to native libraries. There are two accepted
|
|
|
@ -433,7 +432,7 @@ A few examples of how this model can be used are:
|
|
|
|
|
|
|
|
|
|
|
|
On macOS, frameworks behave with the same semantics as a dynamic library.
|
|
|
|
On macOS, frameworks behave with the same semantics as a dynamic library.
|
|
|
|
|
|
|
|
|
|
|
|
# Unsafe blocks
|
|
|
|
## Unsafe blocks
|
|
|
|
|
|
|
|
|
|
|
|
Some operations, like dereferencing raw pointers or calling functions that have been marked
|
|
|
|
Some operations, like dereferencing raw pointers or calling functions that have been marked
|
|
|
|
unsafe are only allowed inside unsafe blocks. Unsafe blocks isolate unsafety and are a promise to
|
|
|
|
unsafe are only allowed inside unsafe blocks. Unsafe blocks isolate unsafety and are a promise to
|
|
|
@ -448,7 +447,7 @@ unsafe fn kaboom(ptr: *const i32) -> i32 { *ptr }
|
|
|
|
|
|
|
|
|
|
|
|
This function can only be called from an `unsafe` block or another `unsafe` function.
|
|
|
|
This function can only be called from an `unsafe` block or another `unsafe` function.
|
|
|
|
|
|
|
|
|
|
|
|
# Accessing foreign globals
|
|
|
|
## Accessing foreign globals
|
|
|
|
|
|
|
|
|
|
|
|
Foreign APIs often export a global variable which could do something like track
|
|
|
|
Foreign APIs often export a global variable which could do something like track
|
|
|
|
global state. In order to access these variables, you declare them in `extern`
|
|
|
|
global state. In order to access these variables, you declare them in `extern`
|
|
|
@ -498,7 +497,7 @@ fn main() {
|
|
|
|
Note that all interaction with a `static mut` is unsafe, both reading and
|
|
|
|
Note that all interaction with a `static mut` is unsafe, both reading and
|
|
|
|
writing. Dealing with global mutable state requires a great deal of care.
|
|
|
|
writing. Dealing with global mutable state requires a great deal of care.
|
|
|
|
|
|
|
|
|
|
|
|
# Foreign calling conventions
|
|
|
|
## Foreign calling conventions
|
|
|
|
|
|
|
|
|
|
|
|
Most foreign code exposes a C ABI, and Rust uses the platform's C calling convention by default when
|
|
|
|
Most foreign code exposes a C ABI, and Rust uses the platform's C calling convention by default when
|
|
|
|
calling foreign functions. Some foreign functions, most notably the Windows API, use other calling
|
|
|
|
calling foreign functions. Some foreign functions, most notably the Windows API, use other calling
|
|
|
@ -540,7 +539,7 @@ however, windows uses the `C` calling convention, so `C` would be used. This
|
|
|
|
means that in our previous example, we could have used `extern "system" { ... }`
|
|
|
|
means that in our previous example, we could have used `extern "system" { ... }`
|
|
|
|
to define a block for all windows systems, not only x86 ones.
|
|
|
|
to define a block for all windows systems, not only x86 ones.
|
|
|
|
|
|
|
|
|
|
|
|
# Interoperability with foreign code
|
|
|
|
## Interoperability with foreign code
|
|
|
|
|
|
|
|
|
|
|
|
Rust guarantees that the layout of a `struct` is compatible with the platform's
|
|
|
|
Rust guarantees that the layout of a `struct` is compatible with the platform's
|
|
|
|
representation in C only if the `#[repr(C)]` attribute is applied to it.
|
|
|
|
representation in C only if the `#[repr(C)]` attribute is applied to it.
|
|
|
@ -565,7 +564,7 @@ The [`libc` crate on crates.io][libc] includes type aliases and function
|
|
|
|
definitions for the C standard library in the `libc` module, and Rust links
|
|
|
|
definitions for the C standard library in the `libc` module, and Rust links
|
|
|
|
against `libc` and `libm` by default.
|
|
|
|
against `libc` and `libm` by default.
|
|
|
|
|
|
|
|
|
|
|
|
# Variadic functions
|
|
|
|
## Variadic functions
|
|
|
|
|
|
|
|
|
|
|
|
In C, functions can be 'variadic', meaning they accept a variable number of arguments. This can
|
|
|
|
In C, functions can be 'variadic', meaning they accept a variable number of arguments. This can
|
|
|
|
be achieved in Rust by specifying `...` within the argument list of a foreign function declaration:
|
|
|
|
be achieved in Rust by specifying `...` within the argument list of a foreign function declaration:
|
|
|
@ -590,7 +589,7 @@ Normal Rust functions can *not* be variadic:
|
|
|
|
fn foo(x: i32, ...) { }
|
|
|
|
fn foo(x: i32, ...) { }
|
|
|
|
```
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
# The "nullable pointer optimization"
|
|
|
|
## The "nullable pointer optimization"
|
|
|
|
|
|
|
|
|
|
|
|
Certain Rust types are defined to never be `null`. This includes references (`&T`,
|
|
|
|
Certain Rust types are defined to never be `null`. This includes references (`&T`,
|
|
|
|
`&mut T`), boxes (`Box<T>`), and function pointers (`extern "abi" fn()`). When
|
|
|
|
`&mut T`), boxes (`Box<T>`), and function pointers (`extern "abi" fn()`). When
|
|
|
@ -655,7 +654,7 @@ void register(void (*f)(int (*)(int), int)) {
|
|
|
|
|
|
|
|
|
|
|
|
No `transmute` required!
|
|
|
|
No `transmute` required!
|
|
|
|
|
|
|
|
|
|
|
|
# Calling Rust code from C
|
|
|
|
## Calling Rust code from C
|
|
|
|
|
|
|
|
|
|
|
|
You may wish to compile Rust code in a way so that it can be called from C. This is
|
|
|
|
You may wish to compile Rust code in a way so that it can be called from C. This is
|
|
|
|
fairly easy, but requires a few things:
|
|
|
|
fairly easy, but requires a few things:
|
|
|
@ -673,7 +672,7 @@ discussed above in "[Foreign Calling
|
|
|
|
Conventions](ffi.html#foreign-calling-conventions)". The `no_mangle`
|
|
|
|
Conventions](ffi.html#foreign-calling-conventions)". The `no_mangle`
|
|
|
|
attribute turns off Rust's name mangling, so that it is easier to link to.
|
|
|
|
attribute turns off Rust's name mangling, so that it is easier to link to.
|
|
|
|
|
|
|
|
|
|
|
|
# FFI and panics
|
|
|
|
## FFI and panics
|
|
|
|
|
|
|
|
|
|
|
|
It’s important to be mindful of `panic!`s when working with FFI. A `panic!`
|
|
|
|
It’s important to be mindful of `panic!`s when working with FFI. A `panic!`
|
|
|
|
across an FFI boundary is undefined behavior. If you’re writing code that may
|
|
|
|
across an FFI boundary is undefined behavior. If you’re writing code that may
|
|
|
@ -702,7 +701,7 @@ for more information.
|
|
|
|
|
|
|
|
|
|
|
|
[`catch_unwind`]: ../std/panic/fn.catch_unwind.html
|
|
|
|
[`catch_unwind`]: ../std/panic/fn.catch_unwind.html
|
|
|
|
|
|
|
|
|
|
|
|
# Representing opaque structs
|
|
|
|
## Representing opaque structs
|
|
|
|
|
|
|
|
|
|
|
|
Sometimes, a C library wants to provide a pointer to something, but not let you
|
|
|
|
Sometimes, a C library wants to provide a pointer to something, but not let you
|
|
|
|
know the internal details of the thing it wants. The simplest way is to use a
|
|
|
|
know the internal details of the thing it wants. The simplest way is to use a
|
|
|
|