Interface de Fonctions Étrangères

RustRustBeginner
Pratiquer maintenant

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

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Dans ce laboratoire, nous étudions l'Interface de Fonctions Étrangères (FFI) de Rust qui permet d'interagir avec des bibliothèques C en déclarant des fonctions étrangères dans un bloc extern et en les annotant avec un attribut #[link] contenant le nom de la bibliothèque étrangère. L'exemple de code montre comment utiliser l'FFI pour appeler des fonctions externes de la bibliothèque libm, telles que le calcul de la racine carrée d'un nombre complexe à précision simple et le calcul du cosinus d'un nombre complexe. Des enveloppes sécurisées sont généralement utilisées autour de ces appels de fonctions étrangères non sécurisées. Le laboratoire inclut également une implémentation minimale de nombres complexes à précision simple et montre comment appeler des API sécurisées encapsulant des opérations non sécurisées.

Note : Si le laboratoire ne spécifie pas de nom de fichier, vous pouvez utiliser n'importe quel nom de fichier que vous voulez. Par exemple, vous pouvez utiliser main.rs, le compiler et l'exécuter avec 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{{"Interface de Fonctions Étrangères"}} rust/floating_types -.-> lab-99280{{"Interface de Fonctions Étrangères"}} rust/string_type -.-> lab-99280{{"Interface de Fonctions Étrangères"}} rust/function_syntax -.-> lab-99280{{"Interface de Fonctions Étrangères"}} rust/expressions_statements -.-> lab-99280{{"Interface de Fonctions Étrangères"}} rust/lifetime_specifiers -.-> lab-99280{{"Interface de Fonctions Étrangères"}} rust/traits -.-> lab-99280{{"Interface de Fonctions Étrangères"}} rust/unsafe_rust -.-> lab-99280{{"Interface de Fonctions Étrangères"}} end

Interface de Fonctions Étrangères

Rust fournit une Interface de Fonctions Étrangères (FFI) pour les bibliothèques C. Les fonctions étrangères doivent être déclarées à l'intérieur d'un bloc extern annoté avec un attribut #[link] contenant le nom de la bibliothèque étrangère.

use std::fmt;

// ce bloc extern se lie à la bibliothèque libm
#[link(name = "m")]
extern {
    // c'est une fonction étrangère
    // qui calcule la racine carrée d'un nombre complexe à précision simple
    fn csqrtf(z: Complex) -> Complex;

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

// Étant donné que l'appel de fonctions étrangères est considéré comme non sécurisé,
// il est courant d'écrire des enveloppes sécurisées autour d'elles.
fn cos(z: Complex) -> Complex {
    unsafe { ccosf(z) }
}

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

    // appeler une fonction étrangère est une opération non sécurisée
    let z_sqrt = unsafe { csqrtf(z) };

    println!("la racine carrée de {:?} est {:?}", z, z_sqrt);

    // appeler une API sécurisée encapsulant une opération non sécurisée
    println!("cos({:?}) = {:?}", z, cos(z));
}

// Implémentation minimale de nombres complexes à précision 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)
        }
    }
}

Sommaire

Félicitations ! Vous avez terminé le laboratoire sur l'Interface de Fonctions Étrangères. Vous pouvez pratiquer d'autres laboratoires sur LabEx pour améliorer vos compétences.