compile if snappy is installed:
```no_run
+# #![feature(libc)]
extern crate libc;
use libc::size_t;
The `extern` block can be extended to cover the entire snappy API:
```no_run
+# #![feature(libc)]
extern crate libc;
use libc::{c_int, size_t};
length is number of elements currently contained, and the capacity is the total size in elements of
the allocated memory. The length is less than or equal to the capacity.
-```
+```rust
+# #![feature(libc)]
# extern crate libc;
# use libc::{c_int, size_t};
# unsafe fn snappy_validate_compressed_buffer(_: *const u8, _: size_t) -> c_int { 0 }
`snappy_compress` function as an output parameter. An output parameter is also passed to retrieve
the true length after compression for setting the length.
-```
+```rust
+# #![feature(libc)]
# extern crate libc;
# use libc::{size_t, c_int};
# unsafe fn snappy_compress(a: *const u8, b: size_t, c: *mut u8,
Decompression is similar, because snappy stores the uncompressed size as part of the compression
format and `snappy_uncompressed_length` will retrieve the exact buffer size required.
-```
+```rust
+# #![feature(libc)]
# extern crate libc;
# use libc::{size_t, c_int};
# unsafe fn snappy_uncompress(compressed: *const u8,
}
```
-For reference, the examples used here are also available as an [library on
+For reference, the examples used here are also available as a [library on
GitHub](https://github.com/thestinger/rust-snappy).
# Destructors
When this occurs, we must use Rust's destructors to provide safety and guarantee
the release of these resources (especially in the case of panic).
+For more about destructors, see the [Drop trait](../std/ops/trait.Drop.html).
+
# Callbacks from C code to Rust functions
Some external libraries require the usage of callbacks to report back their
Rust object. This could be the object that represents the wrapper for the
respective C object.
-This can be achieved by passing an unsafe pointer to the object down to the
+This can be achieved by passing an raw pointer to the object down to the
C library. The C library can then include the pointer to the Rust object in
the notification. This will allow the callback to unsafely access the
referenced Rust object.
The different `kind` values are meant to differentiate how the native library
participates in linkage. From a linkage perspective, the rust compiler creates
two flavors of artifacts: partial (rlib/staticlib) and final (dylib/binary).
-Native dynamic libraries and frameworks are propagated to the final artifact
-boundary, while static libraries are not propagated at all.
+Native dynamic library and framework dependencies are propagated to the final
+artifact boundary, while static library dependencies are not propagated at
+all, because the static libraries are integrated directly into the subsequent
+artifact.
A few examples of how this model can be used are:
On OSX, frameworks behave with the same semantics as a dynamic library.
-## The `link_args` attribute
-
-There is one other way to tell rustc how to customize linking, and that is via
-the `link_args` attribute. This attribute is applied to `extern` blocks and
-specifies raw flags which need to get passed to the linker when producing an
-artifact. An example usage would be:
-
-``` no_run
-#![feature(link_args)]
-
-#[link_args = "-foo -bar -baz"]
-extern {}
-# fn main() {}
-```
-
-Note that this feature is currently hidden behind the `feature(link_args)` gate
-because this is not a sanctioned way of performing linking. Right now rustc
-shells out to the system linker, so it makes sense to provide extra command line
-arguments, but this will not always be the case. In the future rustc may use
-LLVM directly to link native libraries in which case `link_args` will have no
-meaning.
-
-It is highly recommended to *not* use this attribute, and rather use the more
-formal `#[link(...)]` attribute on `extern` blocks instead.
-
# Unsafe blocks
-Some operations, like dereferencing unsafe 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
the compiler that the unsafety does not leak out of the block.
Unsafe functions, on the other hand, advertise it to the world. An unsafe function is written like
this:
-```
-unsafe fn kaboom(ptr: *const int) -> int { *ptr }
+```rust
+unsafe fn kaboom(ptr: *const i32) -> i32 { *ptr }
```
This function can only be called from an `unsafe` block or another `unsafe` function.
blocks with the `static` keyword:
```no_run
+# #![feature(libc)]
extern crate libc;
#[link(name = "readline")]
fn main() {
println!("You have readline version {} installed.",
- rl_readline_version as int);
+ rl_readline_version as i32);
}
```
them.
```no_run
+# #![feature(libc)]
extern crate libc;
use std::ffi::CString;
calling foreign functions. Some foreign functions, most notably the Windows API, use other calling
conventions. Rust provides a way to tell the compiler which convention to use:
-```
+```rust
+# #![feature(libc)]
extern crate libc;
#[cfg(all(target_os = "win32", target_arch = "x86"))]
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:
-```
+```rust
#[no_mangle]
pub extern fn hello_rust() -> *const u8 {
"Hello, world!\0".as_ptr()
Conventions](ffi.html#foreign-calling-conventions)". The `no_mangle`
attribute turns off Rust's name mangling, so that it is easier to link to.
+# FFI and panics
+
+It’s important to be mindful of `panic!`s when working with FFI. This code,
+when called from C, will `abort`:
+
+```rust
+#[no_mangle]
+pub extern fn oh_no() -> ! {
+ panic!("Oops!");
+}
+# fn main() {}
+```
+
+If you’re writing code that may panic, you should run it in another thread,
+so that the panic doesn’t bubble up to C:
+
+```rust
+use std::thread;
+
+#[no_mangle]
+pub extern fn oh_no() -> i32 {
+ let h = thread::spawn(|| {
+ panic!("Oops!");
+ });
+
+ match h.join() {
+ Ok(_) => 1,
+ Err(_) => 0,
+ }
+}
+# fn main() {}
+```
+