Rust-ohjelmoinnin perusteet · Oppitunti

Foreign Function Interface (FFI)

Opitte kutsumaan C-kirjastoja Rustista ja tarjoamaan Rust-funktioita muiden kielten käyttöön FFI:n avulla yhteentoimivuutta varten.

Oppitunti 1/311 vaihetta

Foreign Function Interface (FFI) on ilmainen Rust-ohjelmoinnin perusteet-oppitunti CoddyKitissä. Tämä on oppitunti 1/3. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu Rust-ohjelmoinnin perusteet-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Rust-ohjelmoinnin perusteet-kurssilla on yhteensä 3 oppituntia.

Mikä FFI on?

FFI on lyhenne sanoista Foreign Function Interface. Sen avulla yhdellä ohjelmointikielellä kirjoitetut ohjelmat voivat kutsua toisella kielellä määriteltyjä funktioita tai käyttää sen tietorakenteita.

Rustissa FFI:n avulla voidaan käyttää muilla kielillä, yleisimmin C:llä, kirjoitettua koodia. Tämä on erittäin hyödyllistä, kun Rust halutaan yhdistää olemassa oleviin kirjastoihin tai järjestelmärajapintoihin.

Miksi FFI:tä kannattaa käyttää?

FFI ei ole jokapäiväinen työkalu, mutta se on tehokas, kun tarvitsette:

  • Olemassa olevien C-kirjastojen hyödyntämistä: Monet tehokkaat ja pitkälle kehitetyt kirjastot on kirjoitettu C:llä tai C++:lla. FFI:n avulla Rust voi käyttää niitä suoraan.
  • Järjestelmärajapintoja: Voitte käyttää käyttöjärjestelmän ominaisuuksia, joille voi olla saatavilla vain C-rajapinta.
  • Yhteentoimivuutta: Voitte rakentaa Rust-kirjaston, jota voidaan kutsua muista kielistä, kuten Pythonista, Javasta tai JavaScriptistä Node.js:n kautta.

C:n kutsuminen Rustista: määritys

Jotta voitte kutsua C-funktiota Rustista, teidän on ensin määritettävä sen allekirjoitus käyttämällä extern "C" -lohkoa. Tämä kertoo Rustille, miltä C-funktio näyttää, mutta ei määritä sen toteutusta.

Osa "C" määrittää C:n kutsukäytännön ja varmistaa, että funktiokutsut ovat yhteensopivia.

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

C:n kutsuminen Rustista: `unsafe`-lohko

Rustin keskeinen lupaus on muistin turvallisuus. Kun Rust-koodissa kuitenkin käytetään C-koodia FFI:n kautta, Rust ei voi taata vieraan koodin turvallisuutta.

Siksi jokainen extern "C" -lohkossa määritetty C-funktion kutsu on ympäröitävä unsafe-lohkolla. Tämä ilmaisee kääntäjälle ja muille kehittäjille, että vastaatte itse turvallisuustakeiden toteutumisesta.

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

Tyyppien vastaavuus: Rust ja C

FFI:tä käytettäessä on varmistettava, että Rustin tyypit vastaavat oikein C:n tyyppejä. Rust tarjoaa tätä varten erityisiä tyyppejä moduuleissa std::os::raw ja std::ffi.

  • i32 -> std::os::raw::c_int
  • f32 -> std::os::raw::c_float
  • bool -> std::os::raw::c_uchar (tai vastaava tyyppi, koska C:ssä ei ole standardoitua totuusarvotyyppiä)
  • &str -> *const std::os::raw::c_char (C-merkkijonojen on päätyttävä nollatavuun; tästä huolehtii usein std::ffi::CString)
  • &mut [T] -> *mut T

Käyttäkää aina näitä eksplisiittisiä C-tyyppejä määrittelemättömän toiminnan välttämiseksi.

Esimerkki: C:n `add`-funktion kutsuminen

Oletetaan, että käytettävissämme on C-kirjasto, jossa on funktio int add(int a, int b);. Näin sitä kutsutaan Rustista. Huomaatte, että kokonaislukutyypeissä käytetään tyyppiä c_int.

(Tämä koodi havainnollistaa FFI-syntaksia, mutta se ei toimi ilman ulkoisesti linkitettyä käännettyä C-kirjastoa.)

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

Rustin tarjoaminen C:lle: perusteet

Jotta Rust-funktiota voidaan kutsua C:stä, tarvitaan kaksi asiaa:

  1. #[no_mangle]: Tämä attribuutti estää Rustin kääntäjää muuttamasta funktion nimeä eli tekemästä sille name mangling -muunnosta. C-kääntäjät odottavat yksinkertaisia nimiä, joita ei ole muunnettu.
  2. extern "C": Tämä määrittää, että funktion on käytettävä C:n kutsukäytäntöä, jolloin se on yhteensopiva C:n kanssa.

Esimerkki: Rust-funktio C:tä varten

Tässä on Rust-funktio, joka laskee summan ja jota C-ohjelma voisi kutsua. Huomaatte attribuutit #[no_mangle] ja extern "C".

(Tämä koodi on tarkoitettu käännettäväksi C:n käyttämäksi kirjastoksi, mutta se sisältää main-funktion sisäistä testausta varten tässä ympäristössä.)

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

FFI-muistinhallinta

Muistinhallinta FFI-rajojen yli on erittäin tärkeää. Jos Rust varaa muistia, esimerkiksi merkkijonoa varten, ja välittää osoittimen C:lle, C:n on joko kopioitava tiedot tai huolehdittava niiden oikeaoppisesta vapauttamisesta.

Vastaavasti jos C varaa muistia ja välittää osoittimen Rustille, Rust ei saa vapauttaa sitä, ellei siihen ole nimenomaisesti annettu lupaa. Muussa tapauksessa Rustin on kopioitava tiedot.

Työkalut, kuten std::ffi::CString ja CStr, auttavat käsittelemään C-yhteensopivia merkkijonoja turvallisesti huolehtimalla nollatavuista ja omistajuuden asianmukaisesta siirtämisestä.

FFI:n pikatarkistus

Testataan, miten hyvin ymmärrätte Rustin Foreign Function Interfacen.

FFI: silta maailmojen välillä

Olette oppineet Rustin Foreign Function Interfacesta!

FFI tekee Rustista aidosti tehokkaan yhteentoimivuuden työkalun, jonka avulla voitte:

  • kutsua C-kirjastojen funktioita käyttämällä extern "C" -määrityksiä ja unsafe-lohkoja
  • tarjota Rust-funktioita muiden kielten käyttöön käyttämällä #[no_mangle]-attribuuttia ja pub extern "C" -määritystä
  • käsitellä tyyppien vastaavuuksia huolellisesti std::os::raw -tyyppien avulla

FFI on tehokas työkalu Rustin integroimiseen erilaisiin ekosysteemeihin, mutta muistakaa käyttää sitä harkiten, erityisesti turvallisuuden ja muistinhallinnan osalta!

Aloita maksutta

Opi Rust tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
39
Oppitunnit
144

Usein kysytyt kysymykset

Onko oppitunti ”Foreign Function Interface (FFI)” ilmainen?

Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa Rust-ohjelmoinnin perusteet-oppimispolun 3 oppituntia, myös oppitunnin “Foreign Function Interface (FFI)”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Rust-ohjelmoinnin perusteet-kurssilla on yhteensä 3 oppituntia.

Mitä opin oppitunnilla ”Foreign Function Interface (FFI)”?

Opitte kutsumaan C-kirjastoja Rustista ja tarjoamaan Rust-funktioita muiden kielten käyttöön FFI:n avulla yhteentoimivuutta varten. Harjoittelet Rust-ohjelmoinnin perusteet-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Rust-ohjelmoinnin perusteet-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Rust-ohjelmoinnin perusteet-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 1/3.

Kuinka kauan ”Foreign Function Interface (FFI)”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Rust-ohjelmoinnin perusteet-oppitunnilla?

Kyllä. Jokainen Rust-ohjelmoinnin perusteet-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Foreign Function Interface (FFI)
  2. Rust WebAssemblyksi (WASM)
  3. Benchmarking ja suorituskyvyn optimointi
← Takaisin: Rust-ohjelmoinnin perusteet