【发布时间】:2020-02-22 21:19:03
【问题描述】:
我有一个 C 库,它需要明确定义字符串长度的字符串类型:
#[repr(C)]
pub struct FFIStr {
len: usize,
data: *const u8,
}
因为这种类型用作静态类型,所以我想要一种使用 const 函数或宏安全地声明它的方法(而不是手动设置 len)。
我的第一次尝试是使用宏和len(),但是在versions before 1.39.0 中,无法获得length of a slice as a const fn:
macro_rules! ffi_string {
($x:expr) => {
FFIStr { len: $x.len(), data: $x as *const u8 }
};
}
#[no_mangle]
pub static mut HELLO_WORLD: FFIStr = ffi_string!(b"Hello, world!");
error: core::slice::<impl [T]>::len` is not yet stable as a const function
我的第二次尝试是使用std::mem::size_of<T>,但似乎没有办法在不使用泛型的情况下获取静态数组的类型:
const fn ffi_string<T>(s: &'static T) -> FFIStr {
FFIStr { len: ::std::mem::size_of::<T>(), data: s as *const _ as *const _ }
}
#[no_mangle]
pub static mut HELLO_WORLD: FFIStr = ffi_string(b"Hello, world!");
虽然这很有效(令人惊讶),但它极易被滥用,因为它会疯狂地将你传递给*const u8 的任何内容都转换为*const u8。
const_generics 似乎是一个很好的解决方案,但它们目前不稳定:
const fn ffi_string<const SIZE: usize>(s: &'static [u8; SIZE]) -> FFIStr {
FFIStr { len: SIZE, data: s as *const u8 }
}
#[no_mangle]
pub static mut X: FFIStr = ffi_string(b"Hello, world!");
error[E0658]: const generics are unstable
有没有更好的方法在编译时确定静态数组的大小?
【问题讨论】:
标签: arrays static rust compile-time-constant