Przykładowy kod poniżejJak sprawdzić, czy wskaźnik funkcji przekazywane z C nie jest NULL
Rust część:
#[no_mangle]
pub extern fn call_c_function(value: i32, fun: fn(i32) -> i32) -> i32 {
fun(value)
}
I część C:
int32_t call_c_function(int32_t value, int32_t (*fun)(int32_t));
int32_t triple(int32_t x)
{
return x*3;
}
int main(int argc, char *argv[])
{
int32_t value = 3;
int32_t result = call_c_function(value, triple);
printf("%d tripled is %d\n", value, result);
call_c_function(0, NULL); // Crash here
return EXIT_SUCCESS;
}
oczywiście drugiego naboru z call_c_function
ulegnie awarii. Rust kompilator nie będzie narzekał na niebezpieczny kod wewnątrz call_c_function
, ponieważ z rdzy punktu widzenia ten kod jest bezpieczny. Również nie wolno po prostu napisać:
if !fun.is_null() {
fun(value)
}
ponieważ fun
typ jest fn(i32) -> i32
(nie jest to wskaźnik).
Moje pytanie brzmi: w jaki sposób mogę chronić call_c_function
przed NULL dereferencją wskaźnika? Czy istnieje sposób sprawdzenia, czy wywołanie zwrotne przekazane z C nie jest poprawne?
Może muszę zmienić definicję call_c_function
?
Tak, po prostu sprawdzić, czy zabawa == NULL. Lub zero, jeśli NULL nie jest rzeczą w rdzą. Pamiętajcie, nie znam rdzy bardzo dobrze, ale tak można to zrobić w C. – rost0031
Zobacz tutaj: http://doc.rust-lang.org/book/ffi.html#the-%22nullable-pointer -optymalizacja% 22 – Adrian
@Adrian Thx, tego właśnie szukałem! – ldanko