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());Run
Implementations
用安全的 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 数据,则此函数将返回带有相应 &str
切片的 Cow
::
Borrowed
(
&str
)
。
否则,它将用 U+FFFD REPLACEMENT CHARACTER
替换所有无效的 UTF-8 序列,并返回带有结果的 Cow
::
Owned
(
String
)
。
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> );Run
Trait 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>
[src]
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>
[src]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>
执行转换。