【发布时间】:2015-01-17 14:27:47
【问题描述】:
我想为 C 库编写一个安全的 Rust 包装器。我需要用 Rust 的术语来表达 C 的库原始指针所有权规则。
该库具有其私有结构,例如:struct handle {void *_data},并将 setter 公开为set_data(struct handle*, void *data)。
我想制作该方法的 Rust 版本,签名上写着“data 必须至少与handle 一样长”。
我试过了:
set_data(&'a self, &'a data:…)
但借用检查器似乎将其应用于该函数内的生命周期,而不是对象的整体生命周期。
我也尝试为impl 添加生命周期,但这仍然没有好处。完整的测试用例:
#![allow(unused_variables)]
struct Handle<'a>;
impl<'a> Handle<'a> {
pub fn set_data(&'a mut self, data: &'a DropCanary) {
// save data raw ptr
}
pub fn use_data(&'a self) {
// use data raw ptr
println!("alive?");
}
}
fn main() {
let mut handle = Handle;
let long_enough_lifetime = DropCanary{label:"long"};
{
let short_lifetime = DropCanary{label:"short"};
handle.set_data(&short_lifetime); // This shouldn't be allowed!
handle.set_data(&long_enough_lifetime); // This is OK
}
handle.use_data();
}
/// --- just for testing ---
struct DropCanary {
label: &'static str,
}
impl Drop for DropCanary {
fn drop(&mut self) {
println!("dropped: {}", self.label);
}
}
问题在于以下代码compiles 和输出:
掉线:短
还活着吗?
掉线:长
所以它会导致 use-after-free,因为 Rust 不知道 short_lifetime 必须比 handle 寿命长。
【问题讨论】: