Interfaz de Funciones Extranjeras

RustRustBeginner
Practicar Ahora

This tutorial is from open-source community. Access the source code

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, aprendemos sobre la Interfaz de Funciones Extranjeras (FFI, por sus siglas en inglés) de Rust, que permite interactuar con bibliotecas C al declarar funciones externas dentro de un bloque extern y anotarlas con un atributo #[link] que contiene el nombre de la biblioteca externa. El ejemplo de código demuestra el uso de la FFI para llamar a funciones externas de la biblioteca libm, como calcular la raíz cuadrada de un número complejo de precisión simple y calcular el coseno de un número complejo. A menudo, se utilizan envoltorios seguros alrededor de estas llamadas a funciones externas no seguras. El laboratorio también incluye una implementación mínima de números complejos de precisión simple y demuestra cómo llamar a APIs seguras envueltas en operaciones no seguras.

Nota: Si el laboratorio no especifica un nombre de archivo, puede usar cualquier nombre de archivo que desee. Por ejemplo, puede usar main.rs, compilarlo y ejecutarlo con rustc main.rs &&./main.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("Rust")) -.-> rust/BasicConceptsGroup(["Basic Concepts"]) rust(("Rust")) -.-> rust/DataTypesGroup(["Data Types"]) rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) rust(("Rust")) -.-> rust/MemorySafetyandManagementGroup(["Memory Safety and Management"]) rust(("Rust")) -.-> rust/AdvancedTopicsGroup(["Advanced Topics"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") rust/DataTypesGroup -.-> rust/floating_types("Floating-point Types") rust/DataTypesGroup -.-> rust/string_type("String Type") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("Function Syntax") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("Expressions and Statements") rust/MemorySafetyandManagementGroup -.-> rust/lifetime_specifiers("Lifetime Specifiers") rust/AdvancedTopicsGroup -.-> rust/traits("Traits") rust/AdvancedTopicsGroup -.-> rust/unsafe_rust("Unsafe Rust") subgraph Lab Skills rust/variable_declarations -.-> lab-99280{{"Interfaz de Funciones Extranjeras"}} rust/floating_types -.-> lab-99280{{"Interfaz de Funciones Extranjeras"}} rust/string_type -.-> lab-99280{{"Interfaz de Funciones Extranjeras"}} rust/function_syntax -.-> lab-99280{{"Interfaz de Funciones Extranjeras"}} rust/expressions_statements -.-> lab-99280{{"Interfaz de Funciones Extranjeras"}} rust/lifetime_specifiers -.-> lab-99280{{"Interfaz de Funciones Extranjeras"}} rust/traits -.-> lab-99280{{"Interfaz de Funciones Extranjeras"}} rust/unsafe_rust -.-> lab-99280{{"Interfaz de Funciones Extranjeras"}} end

Interfaz de Funciones Extranjeras

Rust proporciona una Interfaz de Funciones Extranjeras (FFI, por sus siglas en inglés) para bibliotecas C. Las funciones externas deben declararse dentro de un bloque extern anotado con un atributo #[link] que contiene el nombre de la biblioteca externa.

use std::fmt;

// este bloque extern se vincula a la biblioteca libm
#[link(name = "m")]
extern {
    // esta es una función externa
    // que calcula la raíz cuadrada de un número complejo de precisión simple
    fn csqrtf(z: Complex) -> Complex;

    fn ccosf(z: Complex) -> Complex;
}

// Dado que llamar a funciones externas se considera inseguro,
// es común escribir envoltorios seguros alrededor de ellas.
fn cos(z: Complex) -> Complex {
    unsafe { ccosf(z) }
}

fn main() {
    // z = -1 + 0i
    let z = Complex { re: -1., im: 0. };

    // llamar a una función externa es una operación insegura
    let z_sqrt = unsafe { csqrtf(z) };

    println!("la raíz cuadrada de {:?} es {:?}", z, z_sqrt);

    // llamar a la API segura envuelta en una operación insegura
    println!("cos({:?}) = {:?}", z, cos(z));
}

// Implementación mínima de números complejos de precisión simple
#[repr(C)]
#[derive(Clone, Copy)]
struct Complex {
    re: f32,
    im: f32,
}

impl fmt::Debug for Complex {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if self.im < 0. {
            write!(f, "{}-{}i", self.re, -self.im)
        } else {
            write!(f, "{}+{}i", self.re, self.im)
        }
    }
}

Resumen

¡Felicidades! Has completado el laboratorio de Interfaz de Funciones Extranjeras. Puedes practicar más laboratorios en LabEx para mejorar tus habilidades.