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 169 170 171 172 173 174
//! 与 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*(*n*) 操作,因为需要通过扫描字符串中的 nul 终止符来计算长度。
//!
//! * **内部 nul 字符**- 当 C 字符串具有 nul 终止符时,这通常意味着它们中间不能包含 nul 字符 - nul 字符实际上会截断字符串。
//! Rust 字符串 *可以* 中间有 nul 个字符,因为 nul 不必在 Rust 中标记字符串的结尾。
//!
//! # 非 Rust 字符串的表示形式
//!
//! [`CString`] 和 [`CStr`] 在您需要将 UTF-8 字符串与带有 C ABI 的语言 (如 Python) 相互传输时很有用。
//!
//! * **从 Rust 到 C:**[`CString`] 表示一个拥有的,对 C 友好的字符串:它是 nul 终止的,并且没有内部 nul 字符。
//! Rust 代码可以从一个普通字符串中创建一个 [`CString`] (前提是该字符串中间没有 nul 字符),然后使用多种方法获得一个原始的 <code>\*mut [u8]</code>,然后可以作为参数传递给使用字符串的 C 约定的函数。
//!
//!
//! * **从 C 到 Rust:**[`CStr`] 表示借用的 C 字符串; 它是您用来包装从 C 函数获得的原始 <code>\*const [u8]</code> 的内容。[`CStr`] 保证是一个以 nul 结尾的字节数组。
//! 一旦您有了 [`CStr`],您可以将它转换为 Rust <code>&[str]</code>,如果它是有效的 UTF-8,或者通过添加替换字符来有损地转换它。
//!
//! [`OsString`] 和 [`OsStr`] 在您需要在操作系统本身之间传输字符串时很有用,或者在捕获外部命令的输出时很有用。
//! [`OsString`],[`OsStr`] 和 Rust 字符串之间的转换与 [`CString`] 和 [`CStr`] 的转换相似。
//!
//! * [`OsString`] 无损地表示拥有所有权的平台字符串。但是,这种表示不一定采用平台原生的形式。
//! 在 Rust 标准库中,用于传输字符串 to/from 的各种 API,操作系统使用 [`OsString`] 代替纯字符串。
//! 例如,[`env::var_os()`] 用于查询环境变量; 它返回一个 <code>[Option]<[OsString]></code>。如果环境变量存在,您将获得一个 <code>[Some]\(os_string)</code>,然后您可以尝试将其转换为 Rust 字符串。
//! 这将产生一个 [`Result`],以便在环境变量实际上不包含有效的 Unicode 数据的情况下,您的代码可以检测到错误。
//!
//! * [`OsStr`] 无损地表示对平台字符串的借用引用。
//! 但是,这种表示不一定采用平台原生的形式。
//! 可以用类似 [`OsString`] 的方式转换成 UTF-8 Rust 字符串 小提琴。
//!
//! # Conversions
//!
//! ## 在 Unix 上
//!
//! 在 Unix 上,[`OsStr`] 实现了 <code>std::os::unix::ffi::[OsStrExt][unix.OsStrExt]</code> trait,它增加了两个方法,[`from_bytes`] 和 [`as_bytes`]。
//! 这些在字节片之间进行廉价的转换。
//!
//! 此外,在 Unix 上,[`OsString`] 实现了 <code>std::os::unix::ffi::[OsStringExt][unix.OsStringExt]</code> trait,它提供了 [`from_vec`] 和 [`into_vec`] 方法,这些方法使用它们的参数,并获取或生成 [`u8`] 的 vectors。
//!
//! ## 在 Windows 上
//!
//! [`OsStr`] 可以无损地转换为原生 Windows 字符串。并且原生 Windows 字符串可以无损地转换为 [`OsString`]。
//!
//! 在 Windows 上,[`OsStr`] 实现了 <code>std::os::windows::ffi::[OsStrExt][windows.OsStrExt]</code> trait,它提供了一个 [`encode_wide`] 方法。这提供了一个迭代器,可以将其迭代到 [`u16`] 的 vector 中。
//! 追加 nul 字符后,这与原生 Windows 字符串相同。
//!
//! 此外,在 Windows 上 [`OsString`] 实现了
//! <code>std::os::windows:ffi::[OsStringExt][windows.OsStringExt]</code>
//! 一个 trait,它提供了一个 [`from_wide`] 方法来将原生 Windows 字符串 (没有终止的 nul 字符) 转换为 [`OsString`]。
//!
//! [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::set_var"
//! [`env::var_os()`]: crate::env::var_os "env::var_os"
//! [unix.OsStringExt]: crate::os::unix::ffi::OsStringExt "os::unix::ffi::OsStringExt"
//! [`from_vec`]: crate::os::unix::ffi::OsStringExt::from_vec "os::unix::ffi::OsStringExt::from_vec"
//! [`into_vec`]: crate::os::unix::ffi::OsStringExt::into_vec "os::unix::ffi::OsStringExt::into_vec"
//! [unix.OsStrExt]: crate::os::unix::ffi::OsStrExt "os::unix::ffi::OsStrExt"
//! [`from_bytes`]: crate::os::unix::ffi::OsStrExt::from_bytes "os::unix::ffi::OsStrExt::from_bytes"
//! [`as_bytes`]: crate::os::unix::ffi::OsStrExt::as_bytes "os::unix::ffi::OsStrExt::as_bytes"
//! [`OsStrExt`]: crate::os::unix::ffi::OsStrExt "os::unix::ffi::OsStrExt"
//! [windows.OsStrExt]: crate::os::windows::ffi::OsStrExt "os::windows::ffi::OsStrExt"
//! [`encode_wide`]: crate::os::windows::ffi::OsStrExt::encode_wide "os::windows::ffi::OsStrExt::encode_wide"
//! [`collect`]: crate::iter::Iterator::collect "iter::Iterator::collect"
//! [windows.OsStringExt]: crate::os::windows::ffi::OsStringExt "os::windows::ffi::OsStringExt"
//! [`from_wide`]: crate::os::windows::ffi::OsStringExt::from_wide "os::windows::ffi::OsStringExt::from_wide"
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
#![stable(feature = "rust1", since = "1.0.0")]
#[stable(feature = "alloc_c_string", since = "1.64.0")]
pub use alloc::ffi::{CString, FromVecWithNulError, IntoStringError, NulError};
#[stable(feature = "core_c_str", since = "1.64.0")]
pub use core::ffi::{CStr, FromBytesWithNulError};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::os_str::{OsStr, OsString};
#[stable(feature = "core_ffi_c", since = "1.64.0")]
pub use core::ffi::{
c_char, c_double, c_float, c_int, c_long, c_longlong, c_schar, c_short, c_uchar, c_uint,
c_ulong, c_ulonglong, c_ushort,
};
#[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 os_str;