Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

183
Vistas
Cómo verificar si el puntero de función pasado de C no es NULL

Código de ejemplo a continuación

La parte de óxido:

 #[no_mangle] pub extern fn call_c_function(value: i32, fun: fn(i32) -> i32) -> i32 { fun(value) }

Y la parte 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; }

Por supuesto, la segunda llamada de call_c_function . El compilador de Rust no se quejará del código no seguro dentro de call_c_function , porque desde el punto de vista de Rust, este código es seguro. Además, no está permitido simplemente escribir:

 if !fun.is_null() { fun(value) }

porque el tipo fun es fn(i32) -> i32 (no es un puntero).

Entonces, mi pregunta es, ¿cómo puedo proteger call_c_function contra la desreferencia de puntero NULL? ¿Hay alguna forma de verificar si la devolución de llamada pasada desde C no es válida?

¿Tal vez tengo que cambiar la definición de call_c_function ?

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Puede usar Option<...> para representar punteros de función anulables. Es incorrecto tener un valor NULL para un valor de tipo fn(...) por lo que se requiere el contenedor de Option para casos como este.

Por ejemplo,

 #[no_mangle] pub extern "C" fn call_c_function(value: i32, fun: Option<fn(i32) -> i32>) -> i32 { if let Some(f) = fun { f(value) } }

Sin embargo, hay un punto extra: fun es una función de C, pero el tipo fn(...) es una función de Rust. No son directamente compatibles (por ejemplo, sus convenciones de llamadas difieren). Uno necesita usar el tipo extern "C" fn(...) (también conocido como extern fn(...) ) al interactuar con punteros de función C:

 #[no_mangle] pub extern "C" fn call_c_function(value: i32, fun: Option<extern "C" fn(i32) -> i32>) -> i32 { if let Some(f) = fun { f(value) } }
over 4 years ago · Santiago Trujillo Denunciar

0

Puede comparar un puntero generado por un código no seguro con std::ptr::null()

p.ej

 let pw = libc::getpwnam(username.as_ptr() as *const i8); if std::ptr::null() != pw ...

null() en Linux es 0 as *const T No estoy seguro de si eso es universal.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda