1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
//! 与 FFI 绑定有关的实用工具。 //! //! 该模块提供了实用工具来处理跨非 Rust 接口的数据,例如其他编程语言和底层操作系统。它主要用于 FFI (外部函数接口) 绑定和需要与其他语言交换类 C 字符串的代码。 //! //! # Overview //! //! Rust 代表 [`String`] 类型的拥有的字符串,而借用 [`str`] 原语的字符串切片。两者始终都是 UTF-8 编码,并且中间可能包含 nul 个字节,即,如果您查看组成字符串的字节,则其中可能有一个 `\0`。 //! `String` 和 `str` 都明确存储它们的长度。像 C 中的字符串末尾没有 nul 终止符。 //! //! C 字符串不同于 Rust 字符串: //! //! * **编码**-Rust 字符串是 UTF-8,但是 C 字符串可以使用其他编码。如果使用的是来自 C 的字符串,则应显式检查其编码,而不是像在 Rust 中那样假定它是 UTF-8。 //! //! * **字符大小**-C 字符串可以使用 `char` 或 `wchar_t` 大小的字符; 请 **注意** C 的 `char` 与 Rust 的不同。 //! C 标准使这些类型的实际大小易于解释,但是为由每个字符类型组成的字符串定义了不同的 API。Rust 字符串始终为 UTF-8,因此每个不同的 Unicode 字符将以可变的字节数进行编码。 //! Rust 类型 [`char`] 表示 `[Unicode 标量值]`,与 `[Unicode 代码点]` 相似但不相同。 //! //! * **Nul 终止符和隐式字符串长度**-C 字符串通常以 Nul 终止,即,它们的末尾有 `\0` 字符。 //! 字符串缓冲区的长度不存储,而是必须计算; 要计算字符串的长度,C 代码必须手动调用一个函数,例如 `strlen()` 表示基于 char 的字符串,`wcslen()` 表示基于 wchar_t 的字符串。 //! 这些函数返回字符串中不包括 nul 终止符的字符数,因此缓冲区长度实际上是 `len+1` 字符。 //! Rust 字符串没有 nul 终止符; 它们的长度总是存储的,不需要计算。 //! 在 Rust 中,访问字符串的长度是 `O(1)` 操作 (因为存储了长度) ; 在 C 中,它是 `O(length)` 操作,因为需要通过扫描字符串中的 nul 终止符来计算长度。 //! //! * **内部 nul 字符**- 当 C 字符串具有 nul 终止符时,这通常意味着它们中间不能包含 nul 字符 - nul 字符实际上会截断字符串。 //! Rust 字符串 *可以* 中间有 nul 个字符,因为 nul 不必在 Rust 中标记字符串的结尾。 //! //! # 非 Rust 字符串的表示形式 //! //! [`CString`] 当您需要在具有 C ABI 的语言之间来回传输 UTF-8 字符串时 (例如 Python),X 和 [`CStr`] 很有用。 //! //! * **从 Rust 到 C:**[`CString`] 表示一个拥有的,对 C 友好的字符串: 它是 nul 终止的,并且没有内部 nul 字符。 //! Rust 代码可以从普通字符串中创建 [`CString`] (前提是该字符串的中间没有 nul 字符),然后使用多种方法来获取原始的 * mut [[u8]],然后作为参数传递给使用 C 约定的字符串的函数。 //! //! //! * **从 C 到 Rust:**[`CStr`] 表示借用的 C 字符串; 这就是您用来包装从 C 函数获得的原始 `* const`[`u8`] 的方式。[`CStr`] 保证是一个以 nul 结尾的字节数组。 //! 拥有 [`CStr`] 后,可以将其转换为 Rust [`&str`][`str`] (如果它是有效的 UTF-8),或者通过添加替换字符有损地对其进行转换。 //! //! [`OsString`] 当您需要在操作系统本身之间来回传输字符串,或者在捕获外部命令的输出时,X 和 [`OsStr`] 很有用。 //! [`OsString`],[`OsStr`] 和 Rust 字符串之间的转换与 [`CString`] 和 [`CStr`] 的转换相似。 //! //! * [`OsString`] 以操作系统喜欢的任何表示形式表示一个拥有的字符串。在 Rust 标准库中,用于传输字符串 to/from 的各种 API,操作系统使用 [`OsString`] 代替纯字符串。 //! 例如,[`env::var_os()`] 用于查询环境变量; 它返回一个 [`Option`]`<`[`OsString`]`>`。如果环境变量存在,您将得到一个 [`Some`]`(os_string)`,然后您可以 *然后* 尝试将其转换为 Rust 字符串。 //! 这将产生一个 [`Result`],以便在环境变量实际上不包含有效的 Unicode 数据的情况下,您的代码可以检测到错误。 //! //! * [`OsStr`] 表示借用字符串引用的形式,该形式可以传递给操作系统。可以按照与 [`OsString`] 相似的方式将其转换为 UTF-8 Rust 字符串切片。 //! //! # Conversions //! //! ## 在 Unix 上 //! //! 在 Unix 上,[`OsStr`] 实现了 std::ffi::`[`OsStrExt`][unix.OsStrExt] trait,并使用两种方法 [`from_bytes`] 和 [`as_bytes`] 对其进行了扩充。 //! 它们可以进行 UTF-8 字节片和 UTF-8 字节片之间的廉价转换。 //! //! 此外,在 Unix 上,[`OsString`] 实现了 std::ffi::`[OsStringExt]][unix.OsStringExt] trait,它提供了 [`from_vec`] 和 [`into_vec`] 方法,这些方法使用其参数,并采用或产生 vectors 作为 [`u8`]。 //! //! ## 在 Windows 上 //! //! 在 Windows 上,[`OsStr`] 实现了 std::ffi::`[`OsStrExt`][windows.OsStrExt] trait,它提供了 [`encode_wide`] 方法。这提供了一个迭代器,可以将其迭代到 [`u16`] 的 vector 中。 //! //! 另外,在 Windows 上,[`OsString`] 实现了 std::windows: ffi::`[`OsStringExt`][windows.OsStringExt] trait,它提供了 [`from_wide`] 方法。此方法的结果是一个 [`OsString`],它可以无损地往返于 Windows 字符串。 //! //! [Unicode scalar value]: https://www.unicode.org/glossary/#unicode_scalar_value //! [Unicode code point]: https://www.unicode.org/glossary/#code_point //! [`env::set_var()`]: crate::env::set_var //! [`env::var_os()`]: crate::env::var_os //! [unix.OsStringExt]: crate::os::unix::ffi::OsStringExt //! [`from_vec`]: crate::os::unix::ffi::OsStringExt::from_vec //! [`into_vec`]: crate::os::unix::ffi::OsStringExt::into_vec //! [unix.OsStrExt]: crate::os::unix::ffi::OsStrExt //! [`from_bytes`]: crate::os::unix::ffi::OsStrExt::from_bytes //! [`as_bytes`]: crate::os::unix::ffi::OsStrExt::as_bytes //! [`OsStrExt`]: crate::os::unix::ffi::OsStrExt //! [windows.OsStrExt]: crate::os::windows::ffi::OsStrExt //! [`encode_wide`]: crate::os::windows::ffi::OsStrExt::encode_wide //! [`collect`]: crate::iter::Iterator::collect //! [windows.OsStringExt]: crate::os::windows::ffi::OsStringExt //! [`from_wide`]: crate::os::windows::ffi::OsStringExt::from_wide //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! //! #![stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "cstr_from_bytes", since = "1.10.0")] pub use self::c_str::FromBytesWithNulError; #[unstable(feature = "cstring_from_vec_with_nul", issue = "73179")] pub use self::c_str::FromVecWithNulError; #[stable(feature = "rust1", since = "1.0.0")] pub use self::c_str::{CStr, CString, IntoStringError, NulError}; #[stable(feature = "rust1", since = "1.0.0")] pub use self::os_str::{OsStr, OsString}; #[stable(feature = "core_c_void", since = "1.30.0")] pub use core::ffi::c_void; #[unstable( feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ all supported platforms", issue = "44930" )] pub use core::ffi::{VaList, VaListImpl}; mod c_str; mod os_str;