Sie kann, aber die bessere Frage ist sollte Sie?
Da kann man keine Vec
von C konstruieren, würden Sie es in Rust bauen müssen und dann einen Zeiger auf C-C-Code zurückkehren würde den Zeiger auf die Vec
besitzen und würde dann geben sie zurück, wenn do_something_else
aufrufen.
Dann gibt es das Problem, dass Sie die Vec
in C nicht ändern können, entweder durch Erstellen neuer FFI-Methoden, die alle Rust-Methoden spiegeln.
Sie sollten auch wahrscheinlich nicht nehmen weil Rust Referenzen sind garantiert nicht NULL zu sein, und es gibt nichts, was die erzwingt, wenn sie von C. genannt Es ist besser, eine *const Vec<i32>
zu nehmen, behaupten, dass es nicht-NULL und wandle es in eine Referenz um.
Wahrscheinlich möchten Sie ein C-Array über die FFI-Grenze akzeptieren. C-Arrays ist ein Zeiger und eine Länge, so würden Sie beide akzeptieren und Rekonstitution eine Rust Scheibe (da Sie würde das Array nicht besitzen):
use std::slice;
pub extern fn do_something_else(p: *const i32, len: libc::size_t) {
let slice = unsafe {
assert!(!p.is_null());
slice::from_raw_parts(p, len)
};
}
obligatorischer Link zu The Rust FFI Omnibus.
Wenn Sie wirklich benötigt zu tun, was Sie gefragt, wäre es wahrscheinlich so etwas wie folgt aussehen:
extern crate libc;
#[no_mangle]
pub extern fn make_vec() -> *mut Vec<i32> {
Box::into_raw(Box::new(Vec::new()))
}
#[no_mangle]
pub extern fn add_number(vec: *mut Vec<i32>, val: libc::int32_t) {
let vec = unsafe {
assert!(!vec.is_null());
&mut *vec
};
vec.push(val);
}
#[no_mangle]
pub extern fn print_vec(vec: *const Vec<i32>) {
let vec = unsafe {
assert!(!vec.is_null());
&*vec
};
println!("{:?}", vec);
}
#[no_mangle]
pub extern fn drop_vec(vec: *mut Vec<i32>) {
unsafe {
assert!(!vec.is_null());
Box::from_raw(vec);
}
}
und würden gerne (ungetestet) verwendet werden:
// Add extern declarations
int main(int argc, char *argv[]) {
void *v = make_vec(); // Use a real typedef here
add_number(v, 42);
print_vec(v);
drop_vec(v);
}
Du solltest dies unter valgrind ausführen, um sicher zu gehen, dass ich nichts Dummes getan habe.
Ich denke, Sie können Integer-Array-Zeiger auf die Rost-Funktion von C übergeben. Dann können Sie die Vektorscheibe zu Operationen verwenden. – noshusan
@noshusan Du meinst etwas wie 'pub extern fn do_thing (slice: & [i32])' 'dann deklariere es in der C-Seite wie' void do_thing (int32_t slice []) '? –
Ich bin mir nicht sicher, aber Sie können etwas tun wie 'Pub extern fn do_thing (slice: * [i32])' die Deklaration in der c-Seite wie 'void do_thing (int32_t * slice [])'. Hier verwenden Sie raw_pointer, so dass Sie einen unsicheren Block deklarieren müssen. – noshusan