Struct std::ffi::CStr 1.0.0[−][src]
pub struct CStr { /* fields omitted */ }
Expand description
借用的 C 字符串的表示形式。
此类型表示对以 n 结尾的字节数组的引用。
它可以从一个 &[u8]
切片安全地构建,或者从原始 *const c_char
不安全地构建。
然后可以通过执行 UTF-8 验证将其转换为 Rust &str
,或转换为拥有所有权的 CString
。
&CStr
对 CString
如同 &str
对 String
: 每对中的前者都是借用的引用; 后者是拥有的字符串。
请注意,此结构体不是 repr(C)
,不建议放置在 FFI 函数的签名中。
而是,FFI 函数的安全包装程序可以利用不安全的 CStr::from_ptr
构造函数为其他使用者提供安全的接口。
Examples
检查外部 C 字符串:
use std::ffi::CStr;
use std::os::raw::c_char;
extern "C" { fn my_string() -> *const c_char; }
unsafe {
let slice = CStr::from_ptr(my_string());
println!("string buffer size without nul terminator: {}", slice.to_bytes().len());
}
Run传递源自 Rust 的 C 字符串:
use std::ffi::{CString, CStr};
use std::os::raw::c_char;
fn work(data: &CStr) {
extern "C" { fn work_with(data: *const c_char); }
unsafe { work_with(data.as_ptr()) }
}
let s = CString::new("data data data data").expect("CString::new failed");
work(&s);
Run将外部 C 字符串转换为 Rust String
:
use std::ffi::CStr;
use std::os::raw::c_char;
extern "C" { fn my_string() -> *const c_char; }
fn my_string_safe() -> String {
unsafe {
CStr::from_ptr(my_string()).to_string_lossy().into_owned()
}
}
println!("string: {}", my_string_safe());
RunImplementations
用安全的 C 字符串包装器包装原始 C 字符串。
此函数将使用 CStr
包装器包装提供的 ptr
,从而允许检查和互操作非所有的 C 字符串。
由于调用了 slice::from_raw_parts
函数,原始 C 字符串的总大小必须小于 isize::MAX
字节` 在内存中。
由于多种原因,此方法不安全:
- 不能保证
ptr
的有效性。 - 不能保证返回的生命周期是
ptr
的实际生命周期。 - 不能保证
ptr
指向的内存在字符串末尾包含有效的 nul 终止符字节。 - 不能保证
ptr
指向的内存在CStr
被销毁之前不会改变。
Note: 该操作原定为零成本投放,但 目前已通过预先计算长度来实现 字符串。不能保证总是这样。
Examples
use std::ffi::CStr;
use std::os::raw::c_char;
extern "C" {
fn my_string() -> *const c_char;
}
unsafe {
let slice = CStr::from_ptr(my_string());
println!("string returned: {}", slice.to_str().unwrap());
}
Run从字节切片创建 C 字符串包装器。
在确保字节切片以 nul 终止并且不包含任何内部 nul 字节之后,此函数会将提供的 bytes
强制转换为 CStr
包装器。
Examples
use std::ffi::CStr;
let cstr = CStr::from_bytes_with_nul(b"hello\0");
assert!(cstr.is_ok());
Run创建没有尾随 nul 终止符的 CStr
是错误的:
use std::ffi::CStr;
let cstr = CStr::from_bytes_with_nul(b"hello");
assert!(cstr.is_err());
Run使用内部 nul 字节创建 CStr
是错误的:
use std::ffi::CStr;
let cstr = CStr::from_bytes_with_nul(b"he\0llo\0");
assert!(cstr.is_err());
Run从字节切片不安全地创建 C 字符串包装器。
此函数会将提供的 bytes
强制转换为 CStr
包装器,而无需执行任何健全性检查。
所提供的切片必须以 nul 结尾,并且不包含任何内部 nul 字节。
Examples
use std::ffi::{CStr, CString};
unsafe {
let cstring = CString::new("hello").expect("CString::new failed");
let cstr = CStr::from_bytes_with_nul_unchecked(cstring.to_bytes_with_nul());
assert_eq!(cstr, &*cstring);
}
Run返回此 C 字符串的内部指针。
返回的指针在 self
内一直有效,并且指向以 0 字节结尾的连续区域,以表示字符串的结尾。
WARNING
返回的指针是只读的; 对其进行写入 (包括将其传递给进行写入的 C 代码) 会导致未定义的行为。
您有责任确保底层内存不会过早释放。例如,当在 unsafe
块中使用 ptr
时,以下代码将导致未定义的行为:
use std::ffi::CString;
let ptr = CString::new("Hello").expect("CString::new failed").as_ptr();
unsafe {
// `ptr` 是悬垂的
*ptr;
}
Run发生这种情况是因为 as_ptr
返回的指针不携带任何生命周期信息,并且在评估 CString::new("Hello").expect("CString::new failed").as_ptr()
表达式后立即释放了 CString
。
要解决此问题,请将 CString
绑定到本地变量:
use std::ffi::CString;
let hello = CString::new("Hello").expect("CString::new failed");
let ptr = hello.as_ptr();
unsafe {
// `ptr` 有效,因为 `hello` 在作用域内
*ptr;
}
Run这样,hello
中 CString
的生命周期包含 ptr
和 unsafe
块的生命周期。
将此 C 字符串转换为包含尾随 0 字节的字节切片。
此函数与 CStr::to_bytes
等效,除了保留尾随的 nul 终止符而不是将其截断之外。
Note: 目前,此方法已实现为零费用强制转换,但是 计划在 future 中更改其定义以执行 每次调用此方法时的长度计算。
Examples
use std::ffi::CStr;
let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed");
assert_eq!(cstr.to_bytes_with_nul(), b"foo\0");
Run如果 CStr
的内容是有效的 UTF-8 数据,该函数将返回一个 Cow::Borrowed(&str)
和相应的 &str
切片。
否则,它将用 U+FFFD 替换字符
替换任何无效的 UTF-8 序列,并返回 Cow::Owned(&str)
作为结果。
Examples
在包含有效 UTF-8 的 CStr
上调用 to_string_lossy
:
use std::borrow::Cow;
use std::ffi::CStr;
let cstr = CStr::from_bytes_with_nul(b"Hello World\0")
.expect("CStr::from_bytes_with_nul failed");
assert_eq!(cstr.to_string_lossy(), Cow::Borrowed("Hello World"));
Run在包含无效 UTF-8 的 CStr
上调用 to_string_lossy
:
use std::borrow::Cow;
use std::ffi::CStr;
let cstr = CStr::from_bytes_with_nul(b"Hello \xF0\x90\x80World\0")
.expect("CStr::from_bytes_with_nul failed");
assert_eq!(
cstr.to_string_lossy(),
Cow::Owned(String::from("Hello �World")) as Cow<'_, str>
);
RunTrait Implementations
fn from(s: &CStr) -> Box<CStr>ⓘNotable traits for Box<I, A>impl<I, A> Iterator for Box<I, A> where
I: Iterator + ?Sized,
A: Allocator, type Item = <I as Iterator>::Item;impl<F, A> Future for Box<F, A> where
F: Future + Unpin + ?Sized,
A: Allocator + 'static, type Output = <F as Future>::Output;impl<R: Read + ?Sized> Read for Box<R>impl<W: Write + ?Sized> Write for Box<W>
fn from(s: &CStr) -> Box<CStr>ⓘNotable traits for Box<I, A>impl<I, A> Iterator for Box<I, A> where
I: Iterator + ?Sized,
A: Allocator, type Item = <I as Iterator>::Item;impl<F, A> Future for Box<F, A> where
F: Future + Unpin + ?Sized,
A: Allocator + 'static, type Output = <F as Future>::Output;impl<R: Read + ?Sized> Read for Box<R>impl<W: Write + ?Sized> Write for Box<W>
impl<I, A> Iterator for Box<I, A> where
I: Iterator + ?Sized,
A: Allocator, type Item = <I as Iterator>::Item;impl<F, A> Future for Box<F, A> where
F: Future + Unpin + ?Sized,
A: Allocator + 'static, type Output = <F as Future>::Output;impl<R: Read + ?Sized> Read for Box<R>impl<W: Write + ?Sized> Write for Box<W>
执行转换。
如果存在,则此方法返回 self
和 other
值之间的顺序。 Read more