我没有在标准库中找到有关如何制作const &'static CStr
的任何内容。我试图制作自己的宏以将&'static str
文字转换为&'static CStr
:
macro_rules! cstr {
($e: expr) => {{
const buffer: &str = concat!($e, "\0");
unsafe {std::ffi::CStr::from_bytes_with_nul_unchecked(buffer.as_bytes())}
}}
}
但是有两个问题:
expr
包含空字节,则会调用未定义的行为str::as_bytes
不是const
,所以&CStr
不是const有什么方法可以创建const &'static CStr
?
A CStr
是borrowed type,因此不是“单独”制作的。在引擎盖下,它只不过是对CString
的引用,可以通过以下任一方式创建:
CString
(显而易见)。不得删除原始(源)CString
,并且CString
的生存期仅在存在源的情况下才有效CStr
,从一个字节的字节开始。 CStr::from_bytes_with_nul
仅在原始切片时有效(其本身仅在已分配源数据somewhere时有效)通过CStr::from_bytes_with_nul
创建CStr
很简单:
CStr
转换现有切片也很简单:
CString
请注意,它们的生存期显然将取决于您用来创建let cstring:CString = CString::new("foobar".as_bytes()).unwrap();
let cstr:&CStr = cstring.as_c_str();
println!("{:?}", cstr);
的对象的生存期-如其声明中的lifetime参数所指示的
保留后代:let cstr2:&CStr = CStr::from_bytes_with_nul("foobar\0".as_bytes()).unwrap();
println!("{:?}", cstr2);
不是硬性要求
要创建&CStr
,您会很费力,并且需要一个用于特定宏('static
)的外部包装箱,但这是可行的,就像这样:
const &'static CStr
lazy_static
的意义是在定义静态引用时允许函数调用;我们可以利用它来即时构建我们的#[macro_use] extern crate lazy_static;
use std::ffi::CStr;
lazy_static! {
static ref FOO:&'static CStr = unsafe {
CStr::from_bytes_with_nul_unchecked("foobar\0".as_bytes())
};
}
fn test(input: &'static CStr) {
println!("{:?}", FOO.to_str());
}
fn main() {
test(&FOO);
}
,并且由于它是静态引用,因此借用它最多可包含lazy_static
。任务完成。