diff --git a/src/ffi.md b/src/ffi.md index d88cfe27..769a4248 100644 --- a/src/ffi.md +++ b/src/ffi.md @@ -11,7 +11,7 @@ snappy includes a C interface (documented in ## A note about libc Many of these examples use [the `libc` crate][libc], which provides various -type definitions for C types, among other things. If you’re trying these +type definitions for C types, among other things. If you’re trying out these examples yourself, you’ll need to add `libc` to your `Cargo.toml`: ```toml @@ -23,9 +23,8 @@ libc = "0.2.0" ## Prepare the build script -Because [snappy](https://github.com/google/snappy) is a static library by default. -So there is no C++ std linked in the output artifact. -In order to use this foreign library in Rust, we have to manually specify that we want to link stdc++ in our project. +Because [snappy](https://github.com/google/snappy) is a static library by default, so there is no stdc++ linked in the output artifact. +In order to use this foreign library in Rust, we have to manually specify that we want to link stdc++ std to our project. The easiest way to do this is by setting up a build script. First edit `Cargo.toml`, inside `package` add `build = "build.rs"`: @@ -39,7 +38,7 @@ Then create a new file at the root of your workspace, named `build.rs`: ```rust // build.rs fn main() { - println!("cargo:rustc-link-lib=dylib=stdc++"); // This line may be unnecessary for some environment. + println!("cargo:rustc-link-lib=dylib=stdc++"); // This line may be unnecessary for some environments. println!("cargo:rustc-link-search="); } ``` @@ -69,7 +68,7 @@ fn main() { The `extern` block is a list of function signatures in a foreign library, in this case with the platform's C ABI. The `#[link(...)]` attribute is used to -instruct the linker to link against the snappy library so the symbols are +instruct the linker to link against the snappy library so the symbols can be resolved. Foreign functions are assumed to be unsafe so calls to them need to be wrapped @@ -115,7 +114,7 @@ The raw C API needs to be wrapped to provide memory safety and make use of highe like vectors. A library can choose to expose only the safe, high-level interface and hide the unsafe internal details. -Wrapping the functions which expect buffers involves using the `slice::raw` module to manipulate Rust +Wrapping the functions which expect buffers involves using the `slice::raw` module to manipulate Rust's vectors as pointers to memory. Rust's vectors are guaranteed to be a contiguous block of memory. The length is the 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. @@ -262,13 +261,13 @@ mod tests { 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). +the release of these resources (especially in the case of a panic). -For more about destructors, see the [Drop trait](../std/ops/trait.Drop.html). +For more information about destructors, see the [Drop trait](../std/ops/trait.Drop.html). ## Calling Rust code from C -You may wish to compile Rust code in a way so that it can be called from C. +You may wish to compile Rust code in a way that can be called from C. This is fairly easy, but requires a few things. ### Rust side @@ -294,7 +293,7 @@ Then, to compile Rust code as a shared library that can be called from C, add th crate-type = ["cdylib"] ``` -(NOTE: We could also use the `staticlib` crate type but it needs to tweak some linking flags.) +(NOTE: We could also use the `staticlib` crate type but it also requires tweaking some linking flags.) Run `cargo build` and you're ready to go on the Rust side. @@ -332,7 +331,7 @@ Hello from Rust! ``` That's it! -For more realistic example, check the [`cbindgen`]. +For a more realistic example, check the [`cbindgen`]. [`cbindgen`]: https://github.com/eqrion/cbindgen @@ -621,7 +620,7 @@ This is currently hidden behind the `abi_vectorcall` gate and is subject to chan * `win64` * `sysv64` -Most of the abis in this list are self-explanatory, but the `system` abi may +Most of the ABIs in this list are self-explanatory, but the `system` ABI may seem a little odd. This constraint selects whatever the appropriate ABI is for interoperating with the target's libraries. For example, on win32 with a x86 architecture, this means that the abi used would be `stdcall`. On x86_64,