Rust's `extern` Block: Talking to Other Languages
An extern block is Rust's contract for calling code from other languages, like C. You declare external functions and statics, promising they exist. Use it for FFI to call system libraries, but know all calls are unsafe as Rust can't verify them.
Why it exists
Rust needs a way to interoperate with the vast ecosystem of existing code, most of which is written in C or exposes a C-compatible interface. extern blocks provide this bridge, allowing Rust programs to call functions and access data from non-Rust libraries, forming the basis of its Foreign Function Interface (FFI).
The mental model
Think of an extern block as a C header file (.h) translated into Rust syntax. You are not defining new functions, but merely declaring the signatures of functions that are defined elsewhere. You are making a promise to the compiler: "Trust me, a function with this name, these arguments, and this return type exists, and you can call it using this specific calling convention (ABI)."
How it works
You declare an extern block using unsafe extern "ABI" { ... }, where the ABI (Application Binary Interface) string like "C" or "system" specifies the calling convention. Inside, you list function signatures without bodies (ending in a semicolon) and static variables without initializers. Calling these functions or accessing the statics requires an unsafe block because the Rust compiler cannot verify the safety of the external code. It trusts that your declarations are correct.
When to use it
Use extern blocks whenever you need to perform FFI calls. This is common for three main reasons: first, interacting with operating system APIs (like the Windows API or POSIX functions); second, using a high-performance library written in C or C++; third, linking a Rust component into a larger, existing non-Rust application.
When not to use it
Do not use extern blocks for code written purely in Rust. If you are calling functions from another Rust crate, use its public API via the use keyword. extern is specifically for bridging the gap with non-Rust code. Using it for Rust-to-Rust calls bypasses the safety guarantees and ABI stability that Cargo and the compiler provide.
One canonical example
A classic use case is calling the printf function from the standard C library. First, you declare its signature in an extern "C" block, specifying the C calling convention.
extern "C" {
fn printf(format: *const std::ffi::c_char, ...) -> std::ffi::c_int;
}Then, you can call it from within an unsafe block in your Rust code, making sure to use a C-compatible string (null-terminated).
let message = "Hello from Rust!\n\0";unsafe {
printf(message.as_ptr() as *const i8);
}This tells Rust exactly how to format the function call to be understood by the compiled C library.
Interview question
Why does Rust require `unsafe` blocks when calling functions declared within an `extern` block?
- a.The `extern` block is an experimental feature, making its usage inherently unstable.
- b.Extern blocks are exclusively for low-level system calls that inherently involve undefined behavior.
- c.Rust's compiler cannot verify the safety or correctness of the external code.Correct
- d.These functions bypass Rust's strict ownership and borrowing rules, leading to potential memory issues.
Why? this is the answer
The card states that `unsafe` blocks are required because "the Rust compiler cannot verify the safety of the external code." While FFI calls often bypass Rust's ownership rules (Option D), the fundamental reason for `unsafe` is the compiler's inability to make any safety guarantees about code it doesn't control.
Just read this? Test yourself on what you have been reading.
Read the original → doc.rust-lang.org
- #rust
- #ffi
- #unsafe
- #interop
Put your scrolling time to good use
Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on rust — each one lists the topics its interview covers.
See open roles