0Pricing
Learn Rust Coding · Leçon

Interface de fonctions étrangères (FFI)

Apprenez à appeler des bibliothèques C depuis Rust et à exposer des fonctions Rust à d’autres langages à l’aide de la FFI pour assurer l’interopérabilité.

Interface de fonctions étrangères (FFI) est une leçon Learn Rust Coding gratuite sur CoddyKit. Ceci est la leçon 1 sur 3. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Learn Rust Coding, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Learn Rust Coding comprend 3 leçons au total.

Qu'est-ce que la FFI ?

FFI signifie interface de fonctions étrangères. Il s'agit d'un moyen permettant à des programmes écrits dans un langage de programmation d'appeler des fonctions ou d'utiliser des structures de données définies dans un autre langage.

En Rust, la FFI vous permet d'interagir avec du code écrit dans d'autres langages, le plus souvent en C. Elle est particulièrement utile pour intégrer des bibliothèques existantes ou des API système.

Pourquoi utiliser la FFI ?

La FFI n'est pas un outil du quotidien, mais elle est puissante lorsque vous avez besoin de :

  • Tirer parti de bibliothèques C existantes : de nombreuses bibliothèques matures et performantes sont écrites en C/C++. La FFI permet à Rust de les utiliser directement.
  • Utiliser des API système : interagir avec des fonctionnalités du système d'exploitation qui ne disposent parfois que d'interfaces C.
  • Assurer l'interopérabilité : créer une bibliothèque Rust pouvant être appelée depuis d'autres langages (comme Python, Java ou JavaScript via Node.js).

Appeler C depuis Rust : déclaration

Pour appeler une fonction C depuis Rust, vous devez d'abord déclarer sa signature dans un bloc extern "C". Cela indique à Rust à quoi ressemble la fonction C sans fournir son implémentation.

La partie "C" indique la convention d'appel de C, ce qui garantit la compatibilité des appels de fonctions.

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

Appeler C depuis Rust : le bloc `unsafe`

La promesse fondamentale de Rust est la sécurité mémoire. Toutefois, lorsque vous interagissez avec du code C via la FFI, Rust ne peut pas garantir la sécurité du code étranger.

Par conséquent, tout appel à une fonction C déclarée dans un bloc extern "C" doit être placé dans un bloc unsafe. Cela signale au compilateur (ainsi qu'aux autres développeurs) que vous êtes responsable du respect des garanties de sécurité.

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

Correspondance des types : de Rust vers C

Lorsque vous utilisez la FFI, vous devez vous assurer que les types Rust correspondent correctement aux types C. Rust fournit à cette fin des types spécifiques dans std::os::raw et std::ffi.

  • i32 -> std::os::raw::c_int
  • f32 -> std::os::raw::c_float
  • bool -> std::os::raw::c_uchar (ou un type similaire, car C ne possède pas de type booléen standard)
  • &str -> *const std::os::raw::c_char (les chaînes C doivent se terminer par un caractère nul, ce qui est souvent géré par std::ffi::CString)
  • &mut [T] -> *mut T

Utilisez toujours ces types C explicites afin d'éviter un comportement indéfini.

Exemple : appeler une fonction C `add`

Imaginons que nous disposions d'une bibliothèque C contenant une fonction int add(int a, int b);. Voici comment l'appeler depuis Rust. Remarquez l'utilisation de c_int pour les types entiers.

(Ce code illustre la syntaxe de la FFI, mais ne fonctionnera pas sans une bibliothèque C compilée et liée en externe.)

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

Exposer Rust à C : notions de base

Pour rendre une fonction Rust appelable depuis C, vous avez besoin de deux éléments :

  1. #[no_mangle] : cet attribut empêche le compilateur Rust de « modifier » le nom de la fonction. Les compilateurs C attendent des noms simples, non modifiés.
  2. extern "C" : cela indique que la fonction doit utiliser la convention d'appel de C, afin d'être compatible avec C.

Exemple : fonction Rust pour C

Voici une fonction Rust qui calcule une somme et pourrait être appelée depuis un programme C. Remarquez les attributs #[no_mangle] et extern "C".

(Ce code est conçu pour être compilé comme une bibliothèque destinée à C, mais il inclut un main pour les tests internes dans cet environnement.)

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

Gestion de la mémoire avec la FFI

La gestion de la mémoire aux frontières de la FFI est essentielle. Si Rust alloue de la mémoire (par exemple, une chaîne) et transmet un pointeur à C, C doit soit copier les données, soit être chargé de les libérer correctement.

Inversement, si C alloue de la mémoire et transmet un pointeur à Rust, Rust ne doit pas la libérer, sauf instruction explicite en ce sens, ou doit copier les données.

Des outils comme std::ffi::CString et CStr aident à gérer les chaînes compatibles avec C en toute sécurité, en prenant en charge la terminaison par un caractère nul et en garantissant un transfert de propriété approprié.

Vérification rapide sur la FFI

Vérifions votre compréhension de l'interface de fonctions étrangères de Rust.

FFI : un pont entre les mondes

Vous avez découvert l’interface de fonctions étrangères de Rust !

FFI permet à Rust de devenir un véritable moteur d’interopérabilité, en vous permettant de :

  • Appeler des fonctions de bibliothèques C à l’aide de extern "C" et de blocs unsafe.
  • Rendre des fonctions Rust accessibles à d’autres langages à l’aide de #[no_mangle] et de pub extern "C".
  • Gérer soigneusement la correspondance des types avec les types std::os::raw.

FFI est un outil puissant pour intégrer Rust à divers écosystèmes, mais n’oubliez pas l’importance d’une utilisation prudente, notamment en matière de sécurité et de gestion de la mémoire !

Questions Fréquemment Posées

La leçon « Interface de fonctions étrangères (FFI) » est-elle gratuite ?

Oui — le texte complet de « Interface de fonctions étrangères (FFI) » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Learn Rust Coding, passe à CoddyKit PRO. Le cours Learn Rust Coding comprend 3 leçons au total.

Qu'est-ce que j'apprendrai dans « Interface de fonctions étrangères (FFI) » ?

Apprenez à appeler des bibliothèques C depuis Rust et à exposer des fonctions Rust à d’autres langages à l’aide de la FFI pour assurer l’interopérabilité. Tu pratiques Learn Rust Coding avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Learn Rust Coding ?

Aucune expérience préalable n'est requise. Learn Rust Coding sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 3.

Combien de temps prend la leçon « Interface de fonctions étrangères (FFI) » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Learn Rust Coding ?

Oui. Chaque leçon Learn Rust Coding inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Interface de fonctions étrangères (FFI)
  2. Rust vers WebAssembly (WASM)
  3. Évaluation comparative et optimisation des performances
← Retour à Learn Rust Coding