@ -31,7 +31,7 @@ compile if snappy is installed:
use libc::size_t;
#[link(name = "snappy")]
extern {
unsafe extern "C" {
fn snappy_max_compressed_length(source_length: size_t) -> size_t;
}
@ -64,7 +64,7 @@ The `extern` block can be extended to cover the entire snappy API:
use libc::{c_int, size_t};
#[link(name = "snappy")]
extern {
unsafe extern {
fn snappy_compress(input: *const u8,
input_length: size_t,
compressed: *mut u8,
@ -251,7 +251,7 @@ First, we assume you have a lib crate named as `rust_from_c`.
`lib.rs` should have Rust code as following:
```rust
#[no_mangle]
#[unsafe( no_mangle) ]
pub extern "C" fn hello_from_rust() {
println!("Hello from Rust!");
}
@ -331,7 +331,7 @@ extern fn callback(a: i32) {
}
#[link(name = "extlib")]
extern {
unsafe extern {
fn register_callback(cb: extern fn(i32)) -> i32;
fn trigger_callback();
}
@ -383,7 +383,7 @@ struct RustObject {
// Other members...
}
extern "C" fn callback(target: *mut RustObject, a: i32) {
unsafe extern "C" fn callback(target: *mut RustObject, a: i32) {
println!("I'm called from C with value {0}", a);
unsafe {
// Update the value in RustObject with the value received from the callback:
@ -392,9 +392,9 @@ extern "C" fn callback(target: *mut RustObject, a: i32) {
}
#[link(name = "extlib")]
extern {
unsafe extern {
fn register_callback(target: *mut RustObject,
cb: extern fn(*mut RustObject, i32)) -> i32;
cb: unsafe extern fn(*mut RustObject, i32)) -> i32;
fn trigger_callback();
}
@ -523,7 +523,7 @@ blocks with the `static` keyword:
<!-- ignore: requires libc crate -->
```rust,ignore
#[link(name = "readline")]
extern {
unsafe extern {
static rl_readline_version: libc::c_int;
}
@ -543,7 +543,7 @@ use std::ffi::CString;
use std::ptr;
#[link(name = "readline")]
extern {
unsafe extern {
static mut rl_prompt: *const libc::c_char;
}
@ -573,7 +573,7 @@ conventions. Rust provides a way to tell the compiler which convention to use:
#[cfg(all(target_os = "win32", target_arch = "x86"))]
#[link(name = "kernel32")]
#[allow(non_snake_case)]
extern "stdcall" {
unsafe extern "stdcall" {
fn SetEnvironmentVariableA(n: *const u8, v: *const u8) -> libc::c_int;
}
# fn main() { }
@ -635,7 +635,7 @@ In C, functions can be 'variadic', meaning they accept a variable number of argu
be achieved in Rust by specifying `...` within the argument list of a foreign function declaration:
```no_run
extern {
unsafe extern {
fn foo(x: i32, ...);
}
@ -685,7 +685,7 @@ we have function pointers flying across the FFI boundary in both directions.
use libc::c_int;
# #[cfg(hidden)]
extern "C" {
unsafe extern "C" {
/// Registers the callback.
fn register(cb: Option< extern " C " fn ( Option < extern " C " fn ( c_int ) - > c_int>, c_int) -> c_int>);
}
@ -750,8 +750,8 @@ mechanisms (notably C++'s `try`/`catch`).
<!-- ignore: using unstable feature -->
```rust,ignore
#[no_mangle]
extern "C-unwind" fn example() {
#[unsafe( no_mangle) ]
unsafe extern "C-unwind" fn example() {
panic!("Uh oh");
}
```
@ -780,13 +780,13 @@ If the C++ frames have objects, their destructors will be called.
<!-- ignore: using unstable feature -->
```rust,ignore
#[link(...)]
extern "C-unwind" {
unsafe extern "C-unwind" {
// A C++ function that may throw an exception
fn may_throw();
}
#[no_mangle]
extern "C-unwind" fn rust_passthrough() {
#[unsafe( no_mangle) ]
unsafe extern "C-unwind" fn rust_passthrough() {
let b = Box::new(5);
unsafe { may_throw(); }
println!("{:?}", &b);
@ -816,7 +816,7 @@ will be printed.
### `panic` can be stopped at an ABI boundary
```rust
#[no_mangle]
#[unsafe( no_mangle) ]
extern "C" fn assert_nonzero(input: u32) {
assert!(input != 0)
}
@ -833,7 +833,7 @@ process if it panics, you must use [`catch_unwind`]:
```rust
use std::panic::catch_unwind;
#[no_mangle]
#[unsafe( no_mangle) ]
pub extern "C" fn oh_no() -> i32 {
let result = catch_unwind(|| {
panic!("Oops!");
@ -867,7 +867,7 @@ We can represent this in Rust with the `c_void` type:
<!-- ignore: requires libc crate -->
```rust,ignore
extern "C" {
unsafe extern "C" {
pub fn foo(arg: *mut libc::c_void);
pub fn bar(arg: *mut libc::c_void);
}
@ -902,7 +902,7 @@ pub struct Bar {
core::marker::PhantomData< (*mut u8, core::marker::PhantomPinned)>,
}
extern "C" {
unsafe extern "C" {
pub fn foo(arg: *mut Foo);
pub fn bar(arg: *mut Bar);
}