From acf1670892f7c2823db11b831eb0627016a78a2a Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Mon, 5 Nov 2018 01:39:59 +0100 Subject: [PATCH 1/2] interop: point to the cstr-core and cty these are the no_std versions of std::ffi and std::os::raw --- src/interoperability/c-with-rust.md | 26 +++++++++++++----------- src/interoperability/interoperability.md | 8 ++++++-- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/interoperability/c-with-rust.md b/src/interoperability/c-with-rust.md index be24bf4..2eadfdb 100644 --- a/src/interoperability/c-with-rust.md +++ b/src/interoperability/c-with-rust.md @@ -33,13 +33,13 @@ When translated to Rust, this interface would look as such: /* File: cool_bindings.rs */ #[repr(C)] pub struct CoolStruct { - pub x: core::raw::c_int, - pub y: core::raw::c_int, + pub x: cty::c_int, + pub y: cty::c_int, } pub extern "C" fn cool_function( - i: core::raw::c_int, - c: core::raw::c_char, + i: cty::c_int, + c: cty::c_char, cs: *mut CoolStruct ); ``` @@ -54,11 +54,11 @@ pub struct CoolStruct { ... } By default, Rust does not guarantee order, padding, or the size of data included in a `struct`. In order to guarantee compatibility with C code, we include the `#[repr(C)]` attribute, which instructs the Rust compiler to always use the same rules C does for organizing data within a struct. ```rust -pub x: core::raw::c_int, -pub y: core::raw::c_int, +pub x: cty::c_int, +pub y: cty::c_int, ``` -Due to the flexibility of how C or C++ defines an `int` or `char`, it is recommended to use primative data types defined in `core::raw`, which will map types from C to types in Rust +Due to the flexibility of how C or C++ defines an `int` or `char`, it is recommended to use primative data types defined in `cty`, which will map types from C to types in Rust ```rust pub extern "C" fn cool_function( ... ); @@ -67,9 +67,9 @@ pub extern "C" fn cool_function( ... ); This statement defines the signature of a function that uses the C ABI, called `cool_function`. By defining the signature without defining the body of the function, the definition of this function will need to be provided elsewhere, or linked into the final library or binary from a static library. ```rust -i: core::raw::c_int, -c: core::raw::c_char, -cs: *mut CoolStruct + i: cty::c_int, + c: cty::c_char, + cs: *mut CoolStruct ``` Similar to our datatype above, we define the datatypes of the function arguments using C-compatible definitions. We also retain the same argument names, for clarity. @@ -82,7 +82,9 @@ Rather than manually generating these interfaces, which may be tedious and error 1. Gather all C or C++ headers defining interfaces or datatypes you would like to use with Rust 2. Write a `bindings.h` file, which `#include "..."`'s each of the files you gathered in step one -3. Feed this `bindings.h` file, along with any compilation flags used to compile your code into `bindgen`. +3. Feed this `bindings.h` file, along with any compilation flags used to compile + your code into `bindgen`. Tip: use `Builder.ctypes_prefix("cty")` / + `--ctypes-prefix=cty` to make the generated code `#![no_std]` compatible. 4. `bindgen` will produce the generated Rust code to the output of the terminal window. This file may be piped to a file in your project, such as `bindings.rs`. You may use this file in your Rust project to interact with C/C++ code compiled and linked as an external library [bindgen]: https://github.com/rust-lang-nursery/rust-bindgen @@ -126,4 +128,4 @@ fn main() { .file("foo.c") .compile("libfoo.a"); } -``` \ No newline at end of file +``` diff --git a/src/interoperability/interoperability.md b/src/interoperability/interoperability.md index fb70e67..b85f59e 100644 --- a/src/interoperability/interoperability.md +++ b/src/interoperability/interoperability.md @@ -16,8 +16,12 @@ is similar enough or the same. types such as Strings, mapping both `&str` and `String` to C-types that are easier and safer to handle. -For `#![no_std]` environments, there is also `core::raw` that -covers all the primitive types. +Neither of these modules in available in `core`, but you can find a `#![no_std]` +compatible version of `std::ffi::{CStr,CString}` in the [`cstr_core`] crate, and +most of the `std::os::raw` types in the [`cty`] crate. + +[`cstr_core`]: https://crates.io/crates/cstr_core +[`cty`]: https://crates.io/crates/cty | Rust type | Intermediate | C type | |------------|--------------|--------------| From 8d795dba74c6aab93e4a608134cf4a01c55b35de Mon Sep 17 00:00:00 2001 From: James Munns Date: Mon, 5 Nov 2018 01:54:09 +0100 Subject: [PATCH 2/2] fix typo Co-Authored-By: japaric --- src/interoperability/interoperability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interoperability/interoperability.md b/src/interoperability/interoperability.md index b85f59e..166f040 100644 --- a/src/interoperability/interoperability.md +++ b/src/interoperability/interoperability.md @@ -16,7 +16,7 @@ is similar enough or the same. types such as Strings, mapping both `&str` and `String` to C-types that are easier and safer to handle. -Neither of these modules in available in `core`, but you can find a `#![no_std]` +Neither of these modules are available in `core`, but you can find a `#![no_std]` compatible version of `std::ffi::{CStr,CString}` in the [`cstr_core`] crate, and most of the `std::os::raw` types in the [`cty`] crate.