我遇到了两个不同的问题/错误,并且无法找到合适的解决方案。任何帮助将不胜感激
Context,FFI,调用很多C函数,并在生锈结构中包装C类型。
第一个问题是ICE: this path should not cause illegal move。
这迫使我使用&进行所有结构包装。引用如下:
pub struct CassResult<'a> {
result:&'a cql_ffi::CassResult
}
而不是更简单,更可取:
pub struct CassResult {
result:cql_ffi::CassResult
}
否则代码如下:
pub fn first_row(&self) -> Result<CassRow,CassError> {unsafe{
Ok(CassRow{row:*cql_ffi::cass_result_first_row(self.result)})
}}
将导致:
error: internal compiler error: this path should not cause illegal move
Ok(CassRow{row:*cql_ffi::cass_result_first_row(self.result)})
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
所以,我继续使用生命周期管理引用来包装所有内容,在我尝试实现迭代器之前,所有内容都不是很糟糕。在这一点上,我看不到this problem。
method next has an incompatible type for trait: expected concrete lifetime, found bound lifetime parameter
因此,鉴于这两个相互矛盾的问题,我完全陷入困境,无法找到任何方法在类似FFI迭代器的构造周围实现适当的生锈迭代器。
编辑:根据Shep的建议,我得到:
pub struct CassResult {
pub result:cql_ffi::CassResult
}
和
pub fn get_result(&mut future:future) -> Option<CassResult> {unsafe{
let result:&cql_ffi::CassResult = &*cql_ffi::cass_future_get_result(&mut future.future);
Some(CassResult{result:*result})
}}
然后得到:
error: cannot move out of borrowed content
Some(CassResult{result:*result}
有没有办法让这种模式有效?它已经在这个FFI包装代码上重复了。
答案 0 :(得分:0)
只有部分答案:使用"streaming iterator" trait and macro。
我遇到类似的问题,围绕C mysql API制作Rust绑定。结果是这样的代码,而不是本机for
语法:
let query = format!("SELECT id_y, value FROM table_x WHERE id = {}", id_x);
let res = try!(db::run_query(&query));
streaming_for!( row, res.into_iter(), {
let id_y: usize = try!(row.convert::<usize>(0));
let value: f64 = try!(row.convert::<f64>(1));
});
这里res
保存结果并释放内存。 row
的生命周期与res
:
/// Res has an attached lifetime to guard an internal pointer.
struct Res<'a>{ p: *mut c_void }
/// Wrapper created by into_iter()
struct ResMoveIter<'a>{ res: Res<'a> }
impl<'a> /*StreamingIterator<'a, Row<'a>> for*/ ResMoveIter<'a>{
/// Get the next row, or None if no more rows
pub fn next(&'a mut self) -> Option<Row<'a>>{
...
}
}
#[unsafe_destructor]
impl<'a> Drop for Res<'a>{
fn drop(&mut self){
...
}
}
答案 1 :(得分:0)
回答我自己的问题。唯一合适的答案是围绕原始ICE的方式,但正如thepowersgang评论,现在正确的方法是使用:std :: ptr :: read,所以使用这种方法,没有ICE,并希望进展。