Foreign Function Interface

RustRustBeginner
Jetzt üben

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

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

In diesem Lab lernen wir über Rusts Foreign Function Interface (FFI), das es ermöglicht, mit C-Bibliotheken zu interagieren, indem wir fremde Funktionen innerhalb eines extern-Blocks deklarieren und sie mit einem #[link]-Attribut versehen, das den Namen der fremden Bibliothek enthält. Das Codebeispiel zeigt die Verwendung von FFI, um externe Funktionen aus der libm-Bibliothek aufzurufen, wie das Berechnen der Quadratwurzel einer einfachen Gleitkommazahl und die Berechnung des Kosinus einer komplexen Zahl. Safe Wrapper werden üblicherweise um diese unsicheren fremden Funktionsaufrufe verwendet. Das Lab enthält auch eine minimale Implementierung von einfachen Gleitkommazahlen und zeigt, wie man sichere APIs aufruft, die um unsichere Operationen gewrappt sind.

Hinweis: Wenn das Lab keinen Dateinamen angibt, können Sie einen beliebigen Dateinamen verwenden. Beispielsweise können Sie main.rs verwenden, es mit rustc main.rs &&./main kompilieren und ausführen.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) rust(("Rust")) -.-> rust/MemorySafetyandManagementGroup(["Memory Safety and Management"]) rust(("Rust")) -.-> rust/AdvancedTopicsGroup(["Advanced Topics"]) rust(("Rust")) -.-> rust/BasicConceptsGroup(["Basic Concepts"]) rust(("Rust")) -.-> rust/DataTypesGroup(["Data Types"]) 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{{"Foreign Function Interface"}} rust/floating_types -.-> lab-99280{{"Foreign Function Interface"}} rust/string_type -.-> lab-99280{{"Foreign Function Interface"}} rust/function_syntax -.-> lab-99280{{"Foreign Function Interface"}} rust/expressions_statements -.-> lab-99280{{"Foreign Function Interface"}} rust/lifetime_specifiers -.-> lab-99280{{"Foreign Function Interface"}} rust/traits -.-> lab-99280{{"Foreign Function Interface"}} rust/unsafe_rust -.-> lab-99280{{"Foreign Function Interface"}} end

Foreign Function Interface

Rust bietet eine Foreign Function Interface (FFI) für C-Bibliotheken. Fremde Funktionen müssen innerhalb eines extern-Blocks deklariert werden, der mit einem #[link]-Attribut versehen ist, das den Namen der fremden Bibliothek enthält.

use std::fmt;

// Dieser extern-Block verweist auf die libm-Bibliothek
#[link(name = "m")]
extern {
    // Dies ist eine fremde Funktion
    // die die Quadratwurzel einer einfachen Gleitkommazahl berechnet
    fn csqrtf(z: Complex) -> Complex;

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

// Da das Aufrufen von fremden Funktionen als unsicher angesehen wird,
// ist es üblich, sichere Wrapper um sie zu schreiben.
fn cos(z: Complex) -> Complex {
    unsafe { ccosf(z) }
}

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

    // Das Aufrufen einer fremden Funktion ist eine unsichere Operation
    let z_sqrt = unsafe { csqrtf(z) };

    println!("Die Quadratwurzel von {:?} ist {:?}", z, z_sqrt);

    // Aufruf der sicheren API, die um die unsichere Operation gewrappt ist
    println!("cos({:?}) = {:?}", z, cos(z));
}

// Minimalimplementierung von einfachen Gleitkommazahlen
#[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)
        }
    }
}

Zusammenfassung

Herzlichen Glückwunsch! Sie haben das Foreign Function Interface-Lab abgeschlossen. Sie können in LabEx weitere Labs ausprobieren, um Ihre Fähigkeiten zu verbessern.