Pointers 通过'mem::transmute()隐藏泛型的指针`

Pointers 通过'mem::transmute()隐藏泛型的指针`,pointers,rust,ffi,Pointers,Rust,Ffi,我正在尝试为C集合库(Judy Arrays[1])编写Rust绑定,该库只为自身提供存储指针宽度值的空间。我的公司有大量的现有代码,它们使用这个空间直接存储非指针值,如指针宽度整数和小结构。我希望我的Rust绑定允许使用泛型对此类集合进行类型安全访问,但在正确使用指针隐藏语义方面遇到了困难 mem::transmute()函数似乎是实现所需行为的一个潜在工具,但试图在参数化类型的实例上使用它会产生一个让我困惑的编译错误 示例代码: pub struct Example<T> {

我正在尝试为C集合库(Judy Arrays[1])编写Rust绑定,该库只为自身提供存储指针宽度值的空间。我的公司有大量的现有代码,它们使用这个空间直接存储非指针值,如指针宽度整数和小结构。我希望我的Rust绑定允许使用泛型对此类集合进行类型安全访问,但在正确使用指针隐藏语义方面遇到了困难

mem::transmute()
函数似乎是实现所需行为的一个潜在工具,但试图在参数化类型的实例上使用它会产生一个让我困惑的编译错误

示例代码:

pub struct Example<T> {
    v: usize,
    t: PhantomData<T>,
}

impl<T> Example<T> {
    pub fn new() -> Example<T> {
        Example { v: 0, t: PhantomData }
    }

    pub fn insert(&mut self, val: T) {
        unsafe {
            self.v = mem::transmute(val);
        }
    }
}
这是否意味着一个只包含一个参数的类型“在其内部包含类型参数”,因此
transmute()
在这里不起作用?有没有关于正确方法的建议

(,试图获得相同的结果,但不一定通过
mem::transmute()


[1] 我知道现有的
rust judy
项目,但它不支持我想要的指针隐藏,我编写这些新绑定主要是为了学习。

而不是直接将
t
转换为
usize
,您可以将
&t
转换为
&usize

pub fn insert(&mut self, val: T) {
    unsafe {
        let usize_ref: &usize = mem::transmute(&val);
        self.v = *usize_ref;
    }
}
请注意,如果
T
的大小小于
usize
的大小,或者如果对齐要求不同,则可能会从无效的内存位置读取。这可能会导致SEG故障。您可以添加断言以防止出现这种情况:

assert_eq!(mem::size_of::<T>(), mem::size_of::<usize>());
assert!(mem::align_of::<usize>() <= mem::align_of::<T>());
assert\u eq!(mem::size_of::(),mem::size_of::());

断言!(mem::align_of::()修改为第一个问题;将为第二个问题创建新的和链接。这是一个有趣的问题!几乎就像您希望能够编写
,其中sizeof(T)==sizeof(usize)
@Shepmaster:这将是一个棘手的问题,因为
where
子句和
transmute
之间的链接将稍微难以建立(特别是如果可以使用更一般的约束,如
=
).另一方面,它提醒我:;该约束可以对
可转换文件强制执行,其中mem::size_of::()==mem::size_of::()
然后
T
转换为
usize
需要
T:Transmutable
=>完全可确定。我的目标是在编译时强制执行大小兼容性,就像
transmute()
对裸值不起作用。转换引用和添加运行时检查无法达到目的。现在我有了更多的生锈经验,我同意这是目前的做法。构造方法中的断言可以确保代码安全;大小兼容性无法在编译时验证。在您的评论后再次阅读此内容,我相信eve您还需要验证类型的对齐要求。我相应地更新了答案。
assert_eq!(mem::size_of::<T>(), mem::size_of::<usize>());
assert!(mem::align_of::<usize>() <= mem::align_of::<T>());