mirror of https://github.com/rust-lang/nomicon
parent
ff08e31903
commit
288fb5198d
@ -1,45 +0,0 @@
|
|||||||
% Interfacing with other Languages (FFI)
|
|
||||||
|
|
||||||
*Obviously* we'd all love to live in a **glorious** world where everything is
|
|
||||||
written in Rust, Rust, and More Rust. Tragically, programs have been written
|
|
||||||
in Not Rust for over 50 years. Crufty enterprises are doomed to
|
|
||||||
support ancient code bases, and greybeard programmers stuck in their ways
|
|
||||||
*insist* on writing programs in other languages, even to this day!
|
|
||||||
|
|
||||||
In all seriousness, there's a myriad of reasons for your codebase to be a
|
|
||||||
hybrid of different languages, and Rust is well-designed to interface with
|
|
||||||
all of them as painlessly as possible. It does this through the tried and
|
|
||||||
true strategy of all languages: pretend to be C, and understand C.
|
|
||||||
|
|
||||||
Thanks to Rust's minimal runtime and C-like semantics, this is about as
|
|
||||||
painless as FFI with C++. Obviously, most of Rust's features are completely
|
|
||||||
incompatible with other languages: tagged unions, zero-sized-types, dynamically-
|
|
||||||
sized types, destructors, methods, traits, references, and lifetimes are all
|
|
||||||
concepts that you won't be able to expose or accept in your foreign function
|
|
||||||
interface.
|
|
||||||
|
|
||||||
All mapping through C will give you is functions, structs, globals, raw pointers,
|
|
||||||
and C-like enums. That's it. Rust's default data layouts are also incompatible
|
|
||||||
with the C layout. See [the section on data layout][data.html] for details.
|
|
||||||
Long story short: mark FFI structs and enums with `#[repr(C)]`, mark FFI
|
|
||||||
functions as `extern`.
|
|
||||||
|
|
||||||
## Runtime
|
|
||||||
|
|
||||||
Rust's runtime is sufficiently minimal that it requires *no* special handling.
|
|
||||||
You don't need to set anything up. You don't need to tear anything down.
|
|
||||||
Awesome.
|
|
||||||
|
|
||||||
The only runtime detail you *really* need to worry about is unwinding. Rust's
|
|
||||||
unwinding model is not defined to be incompatible with any particular language.
|
|
||||||
That means that if you call Rust from another language and it unwinds into the
|
|
||||||
calling language, this will cause Undefined Behaviour. Similarly, if another
|
|
||||||
language unwinds into Rust, it will also cause Undefined Behaviour.
|
|
||||||
|
|
||||||
Rust can't really do anything about other languages unwinding into it (FFI is unsafe
|
|
||||||
for a reason!), but you can be a good FFI citizen by catching panics in any
|
|
||||||
FFI functions you export. Rust provides `thread::catch_panic` for exactly this.
|
|
||||||
Unfortunately, this API is still unstable.
|
|
||||||
|
|
||||||
## libc
|
|
||||||
|
|
Loading…
Reference in new issue