나는 이것이 무언가 희한한 일임을 알고 있지만 때로는 ffi를 통해 c 라이브러리에 값을 저장 한 다음 c에서 녹 기능에 대한 콜백을 작성하는 것이 도움이되는 경우가 있습니다.안전하지 않은 포인터를 녹여 소유 포인터로 변환 할 수 있습니까?
이런 상황에서 mut * c_void로 저장된 소유 포인터가 있어야하는 상황을 발견했습니다.
이 방법을 forget()과 함께 사용하여 C에 값 을 저장할 수 있으며 상대방에서 mut * T로 비교적 쉽게 부활시킬 수 있지만, 안전하지 않은 포인터와 다시이 상황에서 '안전한'녹 공간으로.
그러나 컴파일러는 & 포인터에서 참조를 이동하는 것에 대해 항상 불만을 토로합니다.
& T 또는 * T를 unsafe로 ~ T로 변환하려면 특별한 방법이 있습니까? 조금 불분명 할 수있다
, 그래서 여기에 구체적인 예입니다 :extern crate libc;
use libc::c_void;
use std::ops::Drop;
use std::intrinsics::forget;
struct Foo { x: int }
impl Drop for Foo {
fn drop(&mut self) {
println!("We discarded our foo thanks!");
}
}
fn main() {
let mut x = ~Foo { x: 10 };
let mut y = & mut *x as * mut Foo;
println!("Address Y: {:x}", y as uint);
let mut z = y as * mut c_void;
println!("Address Z: {:x}", z as uint);
// Forget x so we don't worry about it
unsafe { forget(x); }
// This would normally happen inside the ffi callback where
// the ffi code discards the void * it was holding and returns it.
unsafe {
let mut res_z = z as * mut Foo;
println!("Ressurected Z: {:x}", z as uint);
let mut res_y = & mut (*res_z);
println!("Ressurected Y: {:x}", y as uint);
let mut res_x:~Foo = ~(*res_y);
}
}
때문에 마지막 줄은 컴파일되지 않을 것이다 : 당신은 소멸자가 호출되지 않습니다 그 라인을 제거하면
test.rs:34:28: 34:34 error: cannot move out of dereference of `&mut`-pointer
test.rs:34 let mut res_x:~Foo = ~(*res_y);
; 그 메모리 블록을 다시 '안전한'녹 영역으로 옮기고 블록 범위가 끝나면 올바르게 모으는 방법을 찾고 있습니다.
편집 : 나는 swap()이 이것을 수행하는 방법으로 생각합니다. 그러나 누출없이 올바르게 수행하는 정확한 의미는 여전히 조금 불분명합니다. 예를 들어, https://gist.github.com/shadowmint/11361488 ~ ~ Foo leaks; 소멸자는 잊혀진 ~ Foo에 대해 호출되지만 대신 tmp에서 생성 된 로컬 ~ Foo가 누설됩니다. :/
그게 바로 제가 고맙다고 생각한 것입니다 ~ – Doug