Lær at programmere i Rust · Lektion

Foreign Function Interface (FFI)

Lær at kalde C-biblioteker fra Rust og eksponere Rust-funktioner for andre sprog ved hjælp af FFI for interoperabilitet.

Lektion 1 af 311 trin

Foreign Function Interface (FFI) er en gratis Lær at programmere i Rust-lektion på CoddyKit. Dette er lektion 1 af 3. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Lær at programmere i Rust, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Lær at programmere i Rust-kurset indeholder 3 lektioner i alt.

Hvad er FFI?

FFI står for Foreign Function Interface. Det er en måde, hvorpå programmer skrevet i ét programmeringssprog kan kalde funktioner eller bruge datastrukturer, der er defineret i et andet sprog.

I Rust gør FFI det muligt at interagere med kode skrevet i andre sprog, oftest C. Det er særligt nyttigt, når du vil integrere eksisterende biblioteker eller system-API'er.

Hvorfor bruge FFI?

FFI er ikke et værktøj, du bruger hver dag, men det er effektivt, når du har brug for at:

  • Bruge eksisterende C-biblioteker: Mange højtydende, gennemprøvede biblioteker er skrevet i C/C++. Med FFI kan Rust bruge dem direkte.
  • Bruge system-API'er: Interagere med funktioner i operativsystemet, som måske kun har C-grænseflader.
  • Sikre interoperabilitet: Bygge et Rust-bibliotek, der kan kaldes fra andre sprog som Python, Java eller JavaScript via Node.js.

Kalde C fra Rust: Deklaration

Hvis du vil kalde en C-funktion fra Rust, skal du først deklarere dens signatur ved hjælp af en extern "C"-blok. Det fortæller Rust, hvordan C-funktionen ser ud, uden at implementeringen angives.

Delen "C" angiver C's kaldekonvention, så funktionskald er 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;
}

Kalde C fra Rust: <code>unsafe</code>-blokken

Rusts grundlæggende løfte er hukommelsessikkerhed. Når du interagerer med C-kode via FFI, kan Rust dog ikke garantere sikkerheden af den fremmede kode.

Derfor skal alle kald til en C-funktion, der er deklareret i en extern "C"-blok, pakkes ind i en unsafe-blok. Det signalerer til compileren og andre udviklere, at du selv er ansvarlig for at overholde sikkerhedsgarantierne.

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

Typetilknytning: Rust til C

Når du bruger FFI, skal du sikre, at Rust-typer tilknyttes korrekt til C-typer. Rust tilbyder specifikke typer i std::os::raw og std::ffi til dette formål.

  • i32 -> std::os::raw::c_int
  • f32 -> std::os::raw::c_float
  • bool -> std::os::raw::c_uchar (eller en tilsvarende type, da C ikke har en standardiseret boolesk type)
  • &str -> *const std::os::raw::c_char (C-strenge skal afsluttes med null, hvilket ofte håndteres af std::ffi::CString)
  • &mut [T] -> *mut T

Brug altid disse eksplicitte C-typer for at undgå udefineret opførsel.

Eksempel: Kalde en C-funktion med navnet <code>add</code>

Forestil dig, at vi har et C-bibliotek med funktionen int add(int a, int b);. Sådan kalder vi den fra Rust. Bemærk brugen af c_int til heltalstyper.

(Denne kode demonstrerer FFI-syntaks, men kan ikke køre uden et kompileret C-bibliotek, der er linket 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: Det grundlæggende

Hvis du vil gøre en Rust-funktion kaldbar fra C, skal du bruge to ting:

  1. #[no_mangle]: Denne attribut forhindrer Rusts compiler i at "forvanske" (ændre) funktionens navn. C-compilere forventer enkle navne uden navneforvanskning.
  2. extern "C": Dette angiver, at funktionen skal bruge C's kaldekonvention, så den er kompatibel med C.

Eksempel: Rust-funktion til C

Her er en Rust-funktion, der beregner en sum og kan kaldes fra et C-program. Bemærk attributterne #[no_mangle] og extern "C".

(Denne kode er beregnet til at blive kompileret som et bibliotek til C, men indeholder en main til intern test i dette miljø.)

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

Hukommelseshåndtering med FFI

Hukommelseshåndtering på tværs af FFI-grænser er afgørende. Hvis Rust allokerer hukommelse, f.eks. en streng, og sender en pointer til C, skal C enten kopiere dataene eller selv stå for at frigive dem korrekt.

Omvendt bør Rust ikke frigive hukommelse, hvis C allokerer den og sender en pointer til Rust, medmindre Rust udtrykkeligt får besked på det. Ellers skal Rust kopiere dataene.

Værktøjer som std::ffi::CString og CStr hjælper med at håndtere C-kompatible strenge sikkert ved at håndtere null-afslutning og sikre korrekt overdragelse af ejerskab.

Hurtigtjek af FFI

Lad os teste din forståelse af Rusts Foreign Function Interface.

FFI: En bro mellem verdener

Du har lært om Rusts Foreign Function Interface!

FFI gør Rust til en stærk løsning til interoperabilitet og lader dig:

  • Kalder funktioner fra C-biblioteker ved hjælp af extern "C" og unsafe-blokke.
  • Eksponere Rust-funktioner for andre sprog ved hjælp af #[no_mangle] og pub extern "C".
  • Håndtere typetilknytning omhyggeligt med typer fra std::os::raw.

FFI er et effektivt værktøj til at integrere Rust i forskellige økosystemer, men husk, hvor vigtigt det er at bruge det omhyggeligt, især når det gælder sikkerhed og hukommelseshåndtering!

Gratis at komme i gang

Lær Rust med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
39
Lektioner
144

Ofte stillede spørgsmål

Er lektionen “Foreign Function Interface (FFI)” gratis?

Ja — alle 3 lektioner i læringssporet Lær at programmere i Rust, inklusive “Foreign Function Interface (FFI)”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Lær at programmere i Rust-kurset indeholder 3 lektioner i alt.

Hvad lærer jeg i “Foreign Function Interface (FFI)”?

Lær at kalde C-biblioteker fra Rust og eksponere Rust-funktioner for andre sprog ved hjælp af FFI for interoperabilitet. Du øver dig i Lær at programmere i Rust med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Lær at programmere i Rust?

Der kræves ingen tidligere erfaring. Lær at programmere i Rust på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 3.

Hvor lang tid tager lektionen “Foreign Function Interface (FFI)”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Lær at programmere i Rust-lektion?

Ja. Alle Lær at programmere i Rust-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Foreign Function Interface (FFI)
  2. Rust til WebAssembly (WASM)
  3. Benchmarking og performanceoptimering
← Tilbage til Lær at programmere i Rust