2017-03-01 2 views
1

Ich versuche, etwas Rust-Code mit FFI zu schreiben, das beinhaltet, dass C den Besitz einer lokal erstellten Struktur übernimmt.Wie übertragen Sie das Eigentum an C-Code von Rust?

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

Ich mag die c_function das Eigentum an den lokalen struct c zu nehmen. In C++ konnte durch release für unqiue_ptr erreicht werden. Ich frage mich, ob es in Rust etwas Ähnliches gibt?

Antwort

5

Der std::unique_ptr Typ in C++ entspricht Box in Rust und .release()corresponds to Box::into_raw.

Beachten Sie, dass die C-Funktion das Eigentum an Rust zurückgeben sollte, um die Struktur zu zerstören. Sie können den Speicher nicht mit Cs free oder C++ delete freigeben.

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' einen Template-Parameter hat,' Deleter', Standard ist 'std :: default_delete '. Es könnte zweckdienlich sein, dies zu nutzen, indem eine freiliegende Rost-Funktion bereitgestellt wird, um stattdessen die Löschung durchzuführen. Alternativ können Sie 'std :: default_delete' spezialisieren, so dass alle _instanzen' unique_ptr 'korrekt freigegeben werden. – Anthony

0

Im Grunde hat C-Sprache keine Eigentumsfunktion. C hat nur "Übergabe nach Wert" und "Übergabe nach Zeiger". Wenn Sie den Mauszeiger Ihrer Rust struct in C-Funktion übergeben möchten, sollten Sie wie folgt vorgehen:

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

Siehe auch https://doc.rust-lang.org/book/raw-pointers.html

+0

Dies überträgt kein Eigentumsrecht; der Stapelrahmen besitzt immer noch "c", so dass wenn "c_function" eine Kopie von 'ptr' speichert, die über den Aufruf von' some_function' hinauslebt, die Verwendung dieses Zeigers nach dem Aufruf von 'some_function' endet undefiniertes Verhalten. –

+0

Danke kommentieren, und das ist mein Fehler. Diese Antwort löst das Problem nicht. – termoshtt

Verwandte Themen