]> git.proxmox.com Git - rustc.git/blobdiff - src/doc/trpl/ffi.md
Imported Upstream version 1.2.0+dfsg1
[rustc.git] / src / doc / trpl / ffi.md
index 97e826579fd9bbc473c13c6d2d0bd4c7db0e0ead..917d8dbe196c76826939f168e5717f235ecd21e7 100644 (file)
@@ -12,6 +12,7 @@ The following is a minimal example of calling a foreign function which will
 compile if snappy is installed:
 
 ```no_run
+# #![feature(libc)]
 extern crate libc;
 use libc::size_t;
 
@@ -45,6 +46,7 @@ keeping the binding correct at runtime.
 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};
 
@@ -79,7 +81,8 @@ vectors as pointers to memory. Rust's vectors are guaranteed to be a contiguous
 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 }
@@ -103,7 +106,8 @@ required capacity to hold the compressed output. The vector can then be passed t
 `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,
@@ -129,7 +133,8 @@ pub fn compress(src: &[u8]) -> Vec<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,
@@ -161,7 +166,7 @@ pub fn uncompress(src: &[u8]) -> Option<Vec<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
@@ -170,6 +175,8 @@ Foreign libraries often hand off ownership of resources to the calling code.
 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
@@ -231,7 +238,7 @@ However it is often desired that the callback is targeted to a special
 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.
@@ -335,8 +342,10 @@ Note that frameworks are only available on OSX targets.
 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:
 
@@ -359,42 +368,17 @@ 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.
@@ -406,6 +390,7 @@ global state. In order to access these variables, you declare them in `extern`
 blocks with the `static` keyword:
 
 ```no_run
+# #![feature(libc)]
 extern crate libc;
 
 #[link(name = "readline")]
@@ -415,7 +400,7 @@ extern {
 
 fn main() {
     println!("You have readline version {} installed.",
-             rl_readline_version as int);
+             rl_readline_version as i32);
 }
 ```
 
@@ -424,6 +409,7 @@ interface. To do this, statics can be declared with `mut` so we can mutate
 them.
 
 ```no_run
+# #![feature(libc)]
 extern crate libc;
 
 use std::ffi::CString;
@@ -455,7 +441,8 @@ Most foreign code exposes a C ABI, and Rust uses the platform's C calling conven
 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"))]
@@ -531,7 +518,7 @@ function pointer using the C ABI.
 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()
@@ -544,3 +531,36 @@ discussed above in "[Foreign Calling
 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() {}
+```
+