在 ffi(嵌入式)环境中,当 C 代码需要函数指针(和可选的,通常是 *void 参数)时,通常会使用蹦床,但我们希望让它调用 rust 闭包。
蹦床是一个fn,而一个盒装闭包作为参数提供。fn 代码只是调用闭包。
然而,我似乎无法让借用检查器相信以下代码是安全的,并且似乎认为在对闭包的调用返回后,作为参数给闭包提供的引用(未由闭包捕获)仍然是借用的。
我不确定为什么会出现这种情况,有人可以帮忙如何编译吗?
// Workaround for unstable feature 'trait_alias'
pub trait Callback<'a>: FnMut(&'a mut Context<'a>) {}
impl<'a, T> Callback<'a> for T where T: FnMut(&'a mut Context<'a>) {}
pub fn trampoline(cb_ptr: *mut c_void ) {
let s = "foo";
let mut ctx = Context { s };
unsafe {
let cb = cb_ptr as *mut Box<dyn Callback<'_>>;
(*cb)(&mut ctx);
}
let Context { s, .. } = ctx;
info!("s = {}", &s);
}
Run Code Online (Sandbox Code Playgroud)
错误:
error[E0503]: cannot use `ctx.s` because it was mutably borrowed
--> temp.rs:91:19
|
88 | (*cb)(&mut ctx);
| -------- borrow of `ctx` occurs here
...
91 | let Context { s, .. } = ctx;
| ^
| |
| use of borrowed `ctx`
| borrow later used here
For more information about this error, try `rustc --explain E0503`.
Run Code Online (Sandbox Code Playgroud)
问题似乎出在&'a mut Context<'a>. 这就是说,对上下文的引用需要与上下文中的引用一样长。然而,您实际上并不关心对上下文的引用的生命周期;它只需要在调用闭包期间持续。
更改&'a mut为似乎&mut可以解决问题:
// Workaround for unstable feature 'trait_alias'
pub trait Callback<'a>: FnMut(&mut Context<'a>) {}
impl<'a, T> Callback<'a> for T where T: FnMut(&mut Context<'a>) {}
pub fn trampoline(cb_ptr: *mut c_void ) {
let s = "foo";
let mut ctx = Context { s };
unsafe {
let cb = cb_ptr as *mut Box<dyn Callback<'_>>;
(*cb)(&mut ctx);
}
let Context { s, .. } = ctx;
info!("s = {}", &s);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
70 次 |
| 最近记录: |