Lär dig programmera i Rust · Lektion

Foreign Function Interface (FFI)

Lär er anropa C-bibliotek från Rust och exponera Rust-funktioner för andra språk med FFI för interoperabilitet.

Lektion 1 av 311 steg

Foreign Function Interface (FFI) är en gratis lektion i Lär dig programmera i Rust på CoddyKit. Detta är lektion 1 av 3. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Lär dig programmera i Rust, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Lär dig programmera i Rust innehåller totalt 3 lektioner.

Vad är FFI?

FFI står för Foreign Function Interface. Det är ett sätt för program skrivna i ett programmeringsspråk att anropa funktioner eller använda datastrukturer som definieras i ett annat språk.

I Rust gör FFI det möjligt att samverka med kod skriven i andra språk, oftast C. Det är mycket användbart när Ni vill integrera befintliga bibliotek eller system-API:er.

Varför använda FFI?

FFI är inget verktyg Ni använder varje dag, men det är kraftfullt när Ni behöver:

  • Använda befintliga C-bibliotek: Många mogna bibliotek med hög prestanda är skrivna i C/C++. Med FFI kan Rust använda dem direkt.
  • System-API:er: Samverka med funktioner i operativsystemet som kanske bara har C-gränssnitt.
  • Kompatibilitet: Bygga ett Rust-bibliotek som kan anropas från andra språk, till exempel Python, Java eller JavaScript via Node.js.

Anropa C från Rust: deklaration

För att anropa en C-funktion från Rust måste Ni först deklarera dess signatur med ett extern "C"-block. Det talar om för Rust hur C-funktionen ser ut utan att ange dess implementation.

Delen "C" anger C:s anropskonvention, vilket säkerställer att funktionsanropen är kompatibla.

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

Anropa C från Rust: `unsafe`-blocket

Rusts grundlöfte är minnessäkerhet. När Ni samverkar med C-kod via FFI kan Rust dock inte garantera att den externa koden är säker.

Därför måste alla anrop till en C-funktion som deklarerats i ett extern "C"-block omslutas av ett unsafe-block. Det signalerar till kompilatorn och andra utvecklare att Ni ansvarar för att säkerhetsgarantierna upprätthålls.

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

Typmappning: Rust till C

När Ni använder FFI måste Ni se till att Rust-typer mappas korrekt till C-typer. Rust tillhandahåller särskilda typer i std::os::raw och std::ffi för detta.

  • i32 -> std::os::raw::c_int
  • f32 -> std::os::raw::c_float
  • bool -> std::os::raw::c_uchar (eller en liknande typ, eftersom C saknar en standardiserad boolesk typ)
  • &str -> *const std::os::raw::c_char (C-strängar måste vara nullterminerade, vilket ofta hanteras av std::ffi::CString)
  • &mut [T] -> *mut T

Använd alltid dessa explicita C-typer för att undvika odefinierat beteende.

Exempel: anropa en C-funktion med namnet `add`

Anta att vi har ett C-bibliotek med funktionen int add(int a, int b);. Så här skulle vi anropa den från Rust. Observera användningen av c_int för heltalstyper.

(Den här koden visar FFI-syntax, men kan inte köras utan ett kompilerat C-bibliotek som länkas externt.)

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

Exponera Rust för C: grunderna

För att göra en Rust-funktion anropsbar från C behöver Ni två saker:

  1. #[no_mangle]: Det här attributet hindrar Rust-kompilatorn från att "mangla" (ändra) funktionens namn. C-kompilatorer förväntar sig enkla namn utan namnändring.
  2. extern "C": Detta anger att funktionen ska använda C:s anropskonvention, så att den blir kompatibel med C.

Exempel: Rust-funktion för C

Här är en Rust-funktion som beräknar en summa och kan anropas från ett C-program. Observera attributen #[no_mangle] och extern "C".

(Den här koden är avsedd att kompileras som ett bibliotek för C, men innehåller en main för intern testning i den här miljön.)

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

Minneshantering med FFI

Minneshantering över FFI-gränser är avgörande. Om Rust allokerar minne, till exempel en sträng, och skickar en pekare till C måste C antingen kopiera datan eller ansvara för att frigöra den korrekt.

Omvänt bör Rust inte frigöra minne som C har allokerat och skickat vidare till Rust, såvida Rust inte uttryckligen instrueras att göra det. Annars måste Rust kopiera datan.

Verktyg som std::ffi::CString och CStr hjälper till att hantera C-kompatibla strängar på ett säkert sätt genom att hantera nullterminering och säkerställa korrekt överföring av ägarskap.

Snabbtest om FFI

Låt oss testa Er förståelse av Rusts Foreign Function Interface.

FFI: en bro mellan världar

Ni har lärt Er om Rusts Foreign Function Interface!

FFI gör Rust till ett kraftfullt verktyg för interoperabilitet och låter Er:

  • Anropa funktioner från C-bibliotek med extern "C" och unsafe-block.
  • Exponera Rust-funktioner för andra språk med #[no_mangle] och pub extern "C".
  • Hantera typmappning noggrant med typer från std::os::raw.

FFI är ett kraftfullt verktyg för att integrera Rust i olika ekosystem, men kom ihåg hur viktigt det är att använda det varsamt, särskilt när det gäller säkerhet och minneshantering!

Gratis att börja

Lär dig Rust med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
39
Lektioner
144

Vanliga frågor

Är lektionen ”Foreign Function Interface (FFI)” gratis?

Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Lär dig programmera i Rust, inklusive ”Foreign Function Interface (FFI)”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Lär dig programmera i Rust innehåller totalt 3 lektioner.

Vad lär jag mig i ”Foreign Function Interface (FFI)”?

Lär er anropa C-bibliotek från Rust och exponera Rust-funktioner för andra språk med FFI för interoperabilitet. Ni övar på Lär dig programmera i Rust med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Lär dig programmera i Rust?

Du behöver inga förkunskaper. Utbildningen i Lär dig programmera i Rust på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 3.

Hur lång tid tar lektionen ”Foreign Function Interface (FFI)”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Lär dig programmera i Rust-lektionen?

Ja. Varje Lär dig programmera i Rust-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Foreign Function Interface (FFI)
  2. Rust till WebAssembly (WASM)
  3. Benchmarking och prestandaoptimering
← Tillbaka till Lär dig programmera i Rust