2017-03-01 36 views
1

我嘗試使用FFI編寫一些Rust代碼,它涉及讓C取得一些本地創建的結構的所有權。如何將所有權轉讓給Rust的C代碼?

fn some_function() { 
    let c = SomeStruct::new(); 
    unsafe { 
     c_function(&mut c); 
    } 
} 

我想c_function採取局部struct c的所有權。在C++中,可以通過release獲得unqiue_ptr。我想知道Rust是否有類似的東西?

回答

5

在C++中的std::unique_ptr類型對應於Rust中的和.release()corresponds to Box::into_raw

let c = Box::new(SomeStruct::new()); 
unsafe { 
    c_function(Box::into_raw(c)); 
} 

請注意,C函數應將所有權歸還給Rust來銷燬結構。他們無法使用C的free或C++的delete釋放內存。

pub unsafe extern "C" fn delete_some_struct(ptr: *mut SomeStruct) { 
    Box::from_raw(ptr); // capture the pointer back into a Box, and then drop the Box. 
} 
+0

'的std :: unique_ptr'有一個模板參數,'Deleter',默認爲'std :: default_delete '。通過提供一個暴露的Rust函數來完成刪除操作,可能會更方便。或者,您可能可以專門化'std :: default_delete',以便_all_實例'unique_ptr '正確解除分配。 – Anthony

0

基本上,C語言沒有所有權功能。 C只有「按值傳遞」和「按指針傳遞」。 如果你想你的防鏽結構的指針傳遞到C函數,你應該做到如下:

fn some_function() { 
    let c = SomeStruct::new(); 
    let ptr = &c as *mut c; 
    unsafe { 
     c_function(ptr); 
    } 
} 

參見https://doc.rust-lang.org/book/raw-pointers.html

+0

這不會轉讓所有權;堆棧幀仍然擁有'c',所以如果'c_function'存儲超出'some_function'調用的'ptr'的副本,那麼在調用'some_function'之後使用該指針將是未定義的行爲。 –

+0

謝謝評論,這是我的錯誤。這個答案不能解決問題。 – termoshtt

相關問題