]> git.lizzy.rs Git - rust.git/blob - src/libstd/ffi/mod.rs
bd5fc3fa24a851f9948317c017a74db1cecb0188
[rust.git] / src / libstd / ffi / mod.rs
1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! Utilities related to FFI bindings.
12 //!
13 //! This module provides utilities to handle data across non-Rust
14 //! interfaces, like other programming languages and the underlying
15 //! operating system. It is mainly of use for FFI (Foreign Function
16 //! Interface) bindings and code that needs to exchange C-like strings
17 //! with other languages.
18 //!
19 //! # Overview
20 //!
21 //! Rust represents owned strings with the [`String`] type, and
22 //! borrowed slices of strings with the [`str`] primitive. Both are
23 //! always in UTF-8 encoding, and may contain nul bytes in the middle,
24 //! i.e. if you look at the bytes that make up the string, there may
25 //! be a `\0` among them. Both `String` and `str` store their length
26 //! explicitly; there are no nul terminators at the end of strings
27 //! like in C.
28 //!
29 //! C strings are different from Rust strings:
30 //!
31 //! * **Encodings** - Rust strings are UTF-8, but C strings may use
32 //! other encodings. If you are using a string from C, you should
33 //! check its encoding explicitly, rather than just assuming that it
34 //! is UTF-8 like you can do in Rust.
35 //!
36 //! * **Character size** - C strings may use `char` or `wchar_t`-sized
37 //! characters; please **note** that C's `char` is different from Rust's.
38 //! The C standard leaves the actual sizes of those types open to
39 //! interpretation, but defines different APIs for strings made up of
40 //! each character type. Rust strings are always UTF-8, so different
41 //! Unicode characters will be encoded in a variable number of bytes
42 //! each. The Rust type [`char`] represents a '[Unicode scalar
43 //! value]', which is similar to, but not the same as, a '[Unicode
44 //! code point]'.
45 //!
46 //! * **Nul terminators and implicit string lengths** - Often, C
47 //! strings are nul-terminated, i.e. they have a `\0` character at the
48 //! end. The length of a string buffer is not stored, but has to be
49 //! calculated; to compute the length of a string, C code must
50 //! manually call a function like `strlen()` for `char`-based strings,
51 //! or `wcslen()` for `wchar_t`-based ones. Those functions return
52 //! the number of characters in the string excluding the nul
53 //! terminator, so the buffer length is really `len+1` characters.
54 //! Rust strings don't have a nul terminator; their length is always
55 //! stored and does not need to be calculated. While in Rust
56 //! accessing a string's length is a O(1) operation (because the
57 //! length is stored); in C it is an O(length) operation because the
58 //! length needs to be computed by scanning the string for the nul
59 //! terminator.
60 //!
61 //! * **Internal nul characters** - When C strings have a nul
62 //! terminator character, this usually means that they cannot have nul
63 //! characters in the middle — a nul character would essentially
64 //! truncate the string. Rust strings *can* have nul characters in
65 //! the middle, because nul does not have to mark the end of the
66 //! string in Rust.
67 //!
68 //! # Representations of non-Rust strings
69 //!
70 //! [`CString`] and [`CStr`] are useful when you need to transfer
71 //! UTF-8 strings to and from languages with a C ABI, like Python.
72 //!
73 //! * **From Rust to C:** [`CString`] represents an owned, C-friendly
74 //! string: it is nul-terminated, and has no internal nul characters.
75 //! Rust code can create a `CString` out of a normal string (provided
76 //! that the string doesn't have nul characters in the middle), and
77 //! then use a variety of methods to obtain a raw `*mut u8` that can
78 //! then be passed as an argument to functions which use the C
79 //! conventions for strings.
80 //!
81 //! * **From C to Rust:** [`CStr`] represents a borrowed C string; it
82 //! is what you would use to wrap a raw `*const u8` that you got from
83 //! a C function. A `CStr` is guaranteed to be a nul-terminated array
84 //! of bytes. Once you have a `CStr`, you can convert it to a Rust
85 //! `&str` if it's valid UTF-8, or lossily convert it by adding
86 //! replacement characters.
87 //!
88 //! [`OsString`] and [`OsStr`] are useful when you need to transfer
89 //! strings to and from the operating system itself, or when capturing
90 //! the output of external commands. Conversions between `OsString`,
91 //! `OsStr` and Rust strings work similarly to those for [`CString`]
92 //! and [`CStr`].
93 //!
94 //! * [`OsString`] represents an owned string in whatever
95 //! representation the operating system prefers. In the Rust standard
96 //! library, various APIs that transfer strings to/from the operating
97 //! system use `OsString` instead of plain strings. For example,
98 //! [`env::var_os()`] is used to query environment variables; it
99 //! returns an `Option<OsString>`. If the environment variable exists
100 //! you will get a `Some(os_string)`, which you can *then* try to
101 //! convert to a Rust string. This yields a [`Result<>`], so that
102 //! your code can detect errors in case the environment variable did
103 //! not in fact contain valid Unicode data.
104 //!
105 //! * [`OsStr`] represents a borrowed reference to a string in a
106 //! format that can be passed to the operating system. It can be
107 //! converted into an UTF-8 Rust string slice in a similar way to
108 //! `OsString`.
109 //!
110 //! # Conversions
111 //!
112 //! ## On Unix
113 //!
114 //! On Unix, [`OsStr`] implements the
115 //! `std::os::unix::ffi::`[`OsStrExt`][unix.OsStrExt] trait, which
116 //! augments it with two methods, [`from_bytes`] and [`as_bytes`].
117 //! These do inexpensive conversions from and to UTF-8 byte slices.
118 //!
119 //! Additionally, on Unix [`OsString`] implements the
120 //! `std::os::unix::ffi::`[`OsStringExt`][unix.OsStringExt] trait,
121 //! which provides [`from_vec`] and [`into_vec`] methods that consume
122 //! their arguments, and take or produce vectors of [`u8`].
123 //!
124 //! ## On Windows
125 //!
126 //! On Windows, [`OsStr`] implements the
127 //! `std::os::windows::ffi::`[`OsStrExt`][windows.OsStrExt] trait,
128 //! which provides an [`encode_wide`] method. This provides an
129 //! iterator that can be [`collect`]ed into a vector of [`u16`].
130 //!
131 //! Additionally, on Windows [`OsString`] implements the
132 //! `std::os::windows:ffi::`[`OsStringExt`][windows.OsStringExt]
133 //! trait, which provides a [`from_wide`] method. The result of this
134 //! method is an `OsString` which can be round-tripped to a Windows
135 //! string losslessly.
136 //!
137 //! [`String`]: ../string/struct.String.html
138 //! [`str`]: ../primitive.str.html
139 //! [`char`]: ../primitive.char.html
140 //! [`u8`]: ../primitive.u8.html
141 //! [`u16`]: ../primitive.u16.html
142 //! [Unicode scalar value]: http://www.unicode.org/glossary/#unicode_scalar_value
143 //! [Unicode code point]: http://www.unicode.org/glossary/#code_point
144 //! [`CString`]: struct.CString.html
145 //! [`CStr`]: struct.CStr.html
146 //! [`OsString`]: struct.OsString.html
147 //! [`OsStr`]: struct.OsStr.html
148 //! [`env::set_var()`]: ../env/fn.set_var.html
149 //! [`env::var_os()`]: ../env/fn.var_os.html
150 //! [`Result<>`]: ../result/enum.Result.html
151 //! [unix.OsStringExt]: ../os/unix/ffi/trait.OsStringExt.html
152 //! [`from_vec`]: ../os/unix/ffi/trait.OsStringExt.html#tymethod.from_vec
153 //! [`into_vec`]: ../os/unix/ffi/trait.OsStringExt.html#tymethod.into_vec
154 //! [unix.OsStrExt]: ../os/unix/ffi/trait.OsStrExt.html
155 //! [`from_bytes`]: ../os/unix/ffi/trait.OsStrExt.html#tymethod.from_bytes
156 //! [`as_bytes`]: ../os/unix/ffi/trait.OsStrExt.html#tymethod.as_bytes
157 //! [`OsStrExt`]: ../os/unix/ffi/trait.OsStrExt.html
158 //! [windows.OsStrExt]: ../os/windows/ffi/trait.OsStrExt.html
159 //! [`encode_wide`]: ../os/windows/ffi/trait.OsStrExt.html#tymethod.encode_wide
160 //! [`collect`]: ../iter/trait.Iterator.html#method.collect
161 //! [windows.OsStringExt]: ../os/windows/ffi/trait.OsStringExt.html
162 //! [`from_wide`]: ../os/windows/ffi/trait.OsStringExt.html#tymethod.from_wide
163
164 #![stable(feature = "rust1", since = "1.0.0")]
165
166 #[stable(feature = "rust1", since = "1.0.0")]
167 pub use self::c_str::{CString, CStr, NulError, IntoStringError};
168 #[stable(feature = "cstr_from_bytes", since = "1.10.0")]
169 pub use self::c_str::{FromBytesWithNulError};
170
171 #[stable(feature = "rust1", since = "1.0.0")]
172 pub use self::os_str::{OsString, OsStr};
173
174 #[stable(feature = "raw_os", since = "1.1.0")]
175 pub use core::ffi::c_void;
176
177 #[cfg(not(stage0))]
178 #[unstable(feature = "c_variadic",
179            reason = "the `c_variadic` feature has not been properly tested on \
180                      all supported platforms",
181            issue = "27745")]
182 pub use core::ffi::VaList;
183
184 mod c_str;
185 mod os_str;