Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add safe extern #220

Merged
merged 2 commits into from
Oct 18, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 34 additions & 4 deletions training-slides/src/ffi.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,12 +233,38 @@ Note:

You cannot do `extern "C" fn some_function();` with no function body - you must use the block.

## Primitive types
## Changes in Rust 1.82

Some C types have direct Rust equivalents.
You can now mark external functions as *safe*:

The [`core::ffi`](https://doc.rust-lang.org/stable/core/ffi/index.html) module
also defines a bunch of useful types and aliases.
```rust
unsafe extern "C" {
// This function is basically impossible to call wrong, so let's mark it safe
safe fn do_stuff(x: i32) -> i32;
}

fn main() {
dbg!(do_stuff(3));
}

#[unsafe(export_name = "do_stuff")]
extern "C" fn my_do_stuff(x: i32) -> i32 {
x + 1
}
```

Note:

You can only mark an extern function as `safe` within an `unsafe extern` block.

Also note that in Rust 1.82, `export_name` became an unsafe attribute, along
with `no_mangle` and `link_section`. The old form is still allowed in Edition
2021 and earlier (for backwards compatibility), but you will have to use the new
syntax in Edition 2024.

## Primitive types

Some C types have direct Rust equivalents. See also [`core::ffi`](https://doc.rust-lang.org/stable/core/ffi/index.html).

| C | Rust |
| --------------- | -------------------------- |
Expand All @@ -255,6 +281,10 @@ On some systems, a C `char` is not 8 bits in size. Rust does not support those
platforms, and likely never will. Rust does support platforms where `int` is
only 16-bits in size.

If `T: ?Sized`, then `Box<T>` may be larger than a single pointer as it will
also need to hold the length information. That means it is no longer the same
size and layout as `T*`.

## Calling this

```rust ignore []
Expand Down