Interfaz de funciones foráneas (FFI)
Aprenda a llamar a bibliotecas de C desde Rust y a exponer funciones de Rust a otros lenguajes mediante FFI para lograr interoperabilidad.
Interfaz de funciones foráneas (FFI) es una lección gratuita de Learn Rust Coding en CoddyKit. Esta es la lección 1 de 3. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Learn Rust Coding, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Learn Rust Coding incluye 3 lecciones en total.
¿Qué es FFI?
FFI son las siglas de Foreign Function Interface (interfaz de funciones foráneas). Es una forma de que los programas escritos en un lenguaje de programación llamen a funciones o utilicen estructuras de datos definidas en otro lenguaje.
En Rust, FFI permite interactuar con código escrito en otros lenguajes, especialmente C. Es muy útil para integrar bibliotecas existentes o API del sistema.
¿Por qué usar FFI?
FFI no es una herramienta de uso cotidiano, pero resulta potente cuando necesita:
- Aprovechar bibliotecas existentes de C: Muchas bibliotecas maduras y de alto rendimiento están escritas en C/C++. FFI permite que Rust las utilice directamente.
- Usar API del sistema: Interactuar con funciones del sistema operativo que quizá solo tengan interfaces de C.
- Interoperabilidad: Crear una biblioteca de Rust a la que puedan llamar otros lenguajes (como Python, Java o JavaScript mediante Node.js).
Llamar a C desde Rust: declaración
Para llamar a una función de C desde Rust, primero debe declarar su signatura mediante un bloque extern "C". Esto indica a Rust cómo es la función de C sin proporcionar su implementación.
La parte "C" especifica la convención de llamada de C, lo que garantiza que las llamadas a funciones sean compatibles.
extern "C" {
// Declare C functions here
// Example: int puts(const char *s);
fn puts(s: *const std::os::raw::c_char) -> std::os::raw::c_int;
// Example: int add(int a, int b);
fn add(a: std::os::raw::c_int, b: std::os::raw::c_int) -> std::os::raw::c_int;
}Llamar a C desde Rust: el bloque `unsafe`
La promesa principal de Rust es la seguridad de la memoria. Sin embargo, cuando interactúa con código de C mediante FFI, Rust no puede garantizar la seguridad del código externo.
Por lo tanto, cualquier llamada a una función de C declarada en un bloque extern "C" debe envolverse en un bloque unsafe. Esto indica al compilador y a los demás desarrolladores que usted es responsable de mantener las garantías de seguridad.
extern "C" {
// We're declaring that a C function `puts` exists.
fn puts(s: *const std::os::raw::c_char) -> std::os::raw::c_int;
}
fn main() {
let rust_string = "Hello from Rust via C!";
// C strings need to be null-terminated.
let c_string = std::ffi::CString::new(rust_string).expect("CString failed");
unsafe {
// Calling the C 'puts' function. This requires 'unsafe'.
puts(c_string.as_ptr());
}
println!("C function call demonstrated.");
}Correspondencia de tipos: de Rust a C
Al utilizar FFI, debe asegurarse de que los tipos de Rust se correspondan correctamente con los tipos de C. Rust proporciona tipos específicos en std::os::raw y std::ffi para este propósito.
i32->std::os::raw::c_intf32->std::os::raw::c_floatbool->std::os::raw::c_uchar(o un tipo similar; C no tiene un booleano estándar)&str->*const std::os::raw::c_char(las cadenas de C necesitan terminación nula, que suele gestionarstd::ffi::CString)&mut [T]->*mut T
Utilice siempre estos tipos explícitos de C para evitar comportamientos indefinidos.
Ejemplo: llamar a una función C `add`
Imagine que tenemos una biblioteca de C con una función int add(int a, int b);. Así la llamaríamos desde Rust. Observe el uso de c_int para los tipos enteros.
(Este código demuestra la sintaxis de FFI, pero no se ejecutará sin una biblioteca de C compilada y enlazada externamente.)
extern "C" {
// Declaration of the C function `add`
fn add(a: std::os::raw::c_int, b: std::os::raw::c_int) -> std::os::raw::c_int;
}
fn main() {
let x = 10;
let y = 20;
let result = unsafe {
// Call the C 'add' function within an unsafe block
add(x as std::os::raw::c_int, y as std::os::raw::c_int)
};
println!("Attempted to call C add. Result (if linked): {}", result);
}Exponer Rust a C: conceptos básicos
Para que se pueda llamar a una función de Rust desde C, necesita dos cosas:
#[no_mangle]: Este atributo impide que el compilador de Rust «manglee» (cambie) el nombre de la función. Los compiladores de C esperan nombres simples, sin modificaciones.extern "C": Esto especifica que la función debe usar la convención de llamada de C, lo que la hace compatible con C.
Ejemplo: función de Rust para C
Esta es una función de Rust que calcula una suma y podría ser llamada desde un programa de C. Observe los atributos #[no_mangle] y extern "C".
(Este código está diseñado para compilarse como una biblioteca para C, pero incluye un main para realizar pruebas internas en este entorno.)
#[no_mangle]
pub extern "C" fn rust_add_and_print(
a: std::os::raw::c_int,
b: std::os::raw::c_int
) -> std::os::raw::c_int {
let sum = a + b;
println!("Rust function received: {} + {} = {}", a, b, sum);
sum
}
fn main() {
println!("This Rust code exposes a function for C.");
// We can also call it internally for demonstration
let result = rust_add_and_print(5, 7);
println!("Internal call result: {}", result);
}Gestión de memoria en FFI
La gestión de memoria entre los límites de FFI es fundamental. Si Rust asigna memoria (por ejemplo, para una cadena) y pasa un puntero a C, C debe copiar los datos o encargarse de liberarlos correctamente.
Por el contrario, si C asigna memoria y pasa un puntero a Rust, Rust no debe liberarla a menos que se le indique explícitamente; de lo contrario, debe copiar los datos.
Herramientas como std::ffi::CString y CStr ayudan a gestionar de forma segura las cadenas compatibles con C, ya que se ocupan de la terminación nula y garantizan la transferencia adecuada de la propiedad.
Comprobación rápida de FFI
Comprobemos su comprensión de la interfaz de funciones foráneas de Rust.
FFI: un puente entre mundos
¡Ha aprendido sobre la interfaz de funciones foráneas de Rust!
FFI permite que Rust sea una herramienta verdaderamente potente para la interoperabilidad y le permite:
- Llamar a funciones de bibliotecas de C mediante bloques
extern "C"yunsafe. - Exponer funciones de Rust a otros lenguajes mediante
#[no_mangle]ypub extern "C". - Gestionar cuidadosamente la correspondencia de tipos con los tipos de
std::os::raw.
FFI es una herramienta potente para integrar Rust en diversos ecosistemas, pero recuerde la importancia de utilizarla con cuidado, especialmente en lo relacionado con la seguridad y la gestión de memoria.
Preguntas frecuentes
¿La lección «Interfaz de funciones foráneas (FFI)» es gratis?
Sí — el texto completo de «Interfaz de funciones foráneas (FFI)» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Learn Rust Coding, actualiza a CoddyKit PRO. El curso de Learn Rust Coding incluye 3 lecciones en total.
¿Qué aprenderé en «Interfaz de funciones foráneas (FFI)»?
Aprenda a llamar a bibliotecas de C desde Rust y a exponer funciones de Rust a otros lenguajes mediante FFI para lograr interoperabilidad. Practicas Learn Rust Coding con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Learn Rust Coding?
No se requiere experiencia previa. Learn Rust Coding en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 3.
¿Cuánto tiempo toma la lección «Interfaz de funciones foráneas (FFI)»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Learn Rust Coding?
Sí. Cada lección de Learn Rust Coding incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Interfaz de funciones foráneas (FFI)
- De Rust a WebAssembly (WASM)
- Benchmarking y ajuste del rendimiento