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;