Lær Rust-programmering · leksjon

Foreign Function Interface (FFI)

Lær å kalle C-biblioteker fra Rust og eksponere Rust-funksjoner for andre språk ved hjelp av FFI for interoperabilitet.

Leksjon 1 av 311 trinn

Foreign Function Interface (FFI) er en gratis leksjon i Lær Rust-programmering på CoddyKit. Dette er leksjon 1 av 3. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Lær Rust-programmering, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Lær Rust-programmering inneholder totalt 3 leksjoner.

Hva er FFI?

FFI står for Foreign Function Interface. Det er en måte for programmer skrevet i ett programmeringsspråk å kalle funksjoner eller bruke datastrukturer som er definert i et annet språk.

I Rust lar FFI deg samhandle med kode skrevet i andre språk, vanligvis C. Dette er svært nyttig når du skal integrere eksisterende biblioteker eller system-API-er.

Hvorfor bruke FFI?

FFI er ikke et verktøy du bruker hver dag, men det er kraftig når du trenger å:

  • Utnytte eksisterende C-biblioteker: Mange biblioteker med høy ytelse og lang historikk er skrevet i C/C++. FFI lar Rust bruke dem direkte.
  • System-API-er: Samhandle med funksjoner i operativsystemet som kanskje bare har C-grensesnitt.
  • Samhandling mellom språk: Bygge et Rust-bibliotek som kan kalles fra andre språk, som Python, Java eller JavaScript via Node.js.

Kalle C fra Rust: Erklæring

For å kalle en C-funksjon fra Rust må du først deklarere signaturen dens ved hjelp av en extern "C"-blokk. Dette forteller Rust hvordan C-funksjonen ser ut, uten å oppgi implementasjonen.

Delen "C" angir C-ens kallkonvensjon, slik at funksjonskallene blir kompatible.

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;
}

Kalle C fra Rust: `unsafe`-blokken

Rusts viktigste løfte er minnesikkerhet. Når du samhandler med C-kode via FFI, kan Rust imidlertid ikke garantere at den eksterne koden er sikker.

Derfor må alle kall til en C-funksjon som er deklarert i en extern "C"-blokk, pakkes inn i en unsafe-blokk. Dette signaliserer til kompilatoren og andre utviklere at du selv har ansvaret for å opprettholde sikkerhetsgarantiene.

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.");
}

Typekobling: Rust til C

Når du bruker FFI, må du sørge for at Rust-typene kobles riktig til C-typene. Rust tilbyr spesifikke typer i std::os::raw og std::ffi til dette formålet.

  • i32 -> std::os::raw::c_int
  • f32 -> std::os::raw::c_float
  • bool -> std::os::raw::c_uchar (eller en tilsvarende type, siden C ikke har en standard boolsk type)
  • &str -> *const std::os::raw::c_char (C-strenger må avsluttes med null, noe som ofte håndteres av std::ffi::CString)
  • &mut [T] -> *mut T

Bruk alltid disse eksplisitte C-typene for å unngå udefinert oppførsel.

Eksempel: Kalle en C-`add`-funksjon

Tenk deg at vi har et C-bibliotek med funksjonen int add(int a, int b);. Slik kan vi kalle den fra Rust. Legg merke til bruken av c_int for heltallstyper.

(Denne koden demonstrerer FFI-syntaks, men kan ikke kjøres uten et kompilert C-bibliotek som er koblet inn eksternt.)

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);
}

Eksponere Rust for C: Grunnleggende

For å gjøre en Rust-funksjon kallbar fra C, trenger du to ting:

  1. #[no_mangle]: Dette attributtet hindrer Rust-kompilatoren i å «mangle» (endre) funksjonsnavnet. C-kompilatorer forventer enkle navn uten navneomforming.
  2. extern "C": Dette angir at funksjonen skal bruke C-ens kallkonvensjon, slik at den blir kompatibel med C.

Eksempel: Rust-funksjon for C

Her er en Rust-funksjon som beregner en sum og kan kalles fra et C-program. Legg merke til attributtene #[no_mangle] og extern "C".

(Denne koden er laget for å kompileres som et bibliotek for C, men inneholder en main for intern testing i dette miljøet.)

#[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);
}

Minnestyring med FFI

Minnestyring på tvers av FFI-grenser er avgjørende. Hvis Rust allokerer minne, for eksempel en streng, og sender en peker til C, må C enten kopiere dataene eller ha ansvaret for å frigjøre dem på riktig måte.

Hvis C allokerer minne og sender en peker til Rust, bør ikke Rust frigjøre det med mindre det uttrykkelig er avtalt. Alternativt må Rust kopiere dataene.

Verktøy som std::ffi::CString og CStr bidrar til å håndtere C-kompatible strenger på en sikker måte ved å håndtere nullterminering og sikre korrekt overføring av eierskap.

Kort FFI-test

La oss teste forståelsen Deres av Rusts Foreign Function Interface.

FFI: En bro mellom verdener

De har lært om Rusts Foreign Function Interface!

FFI gjør Rust til et svært kraftig verktøy for samhandling mellom språk, og lar Dem:

  • Kalle funksjoner fra C-biblioteker ved hjelp av extern "C" og unsafe-blokker.
  • Eksponere Rust-funksjoner for andre språk ved hjelp av #[no_mangle] og pub extern "C".
  • Håndtere typekobling nøye ved hjelp av typer fra std::os::raw.

FFI er et kraftig verktøy for å integrere Rust i ulike økosystemer, men husk hvor viktig det er å bruke det med omtanke, særlig når det gjelder sikkerhet og minnestyring!

Gratis å komme i gang

Lær deg Rust med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
39
Leksjoner
144

Ofte stilte spørsmål

Er leksjonen «Foreign Function Interface (FFI)» gratis?

Ja – du kan lese valgfritt 3 av leksjonene i læringsstien Lær Rust-programmering, inkludert «Foreign Function Interface (FFI)», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i Lær Rust-programmering inneholder totalt 3 leksjoner.

Hva lærer jeg i «Foreign Function Interface (FFI)»?

Lær å kalle C-biblioteker fra Rust og eksponere Rust-funksjoner for andre språk ved hjelp av FFI for interoperabilitet. Du øver på Lær Rust-programmering med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Lær Rust-programmering?

Ingen tidligere erfaring er nødvendig. Lær Rust-programmering på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 1 av 3.

Hvor lang tid tar leksjonen «Foreign Function Interface (FFI)»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Lær Rust-programmering-leksjonen?

Ja. Alle Lær Rust-programmering-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Foreign Function Interface (FFI)
  2. Rust til WebAssembly (WASM)
  3. Benchmarking og ytelsesjustering
← Tilbake til Lær Rust-programmering