Foreign Function Interface (FFI)
Impari a chiamare librerie C da Rust e a esporre funzioni Rust ad altri linguaggi utilizzando FFI per garantire l’interoperabilità.
Foreign Function Interface (FFI) è una lezione Learn Rust Coding gratuita su CoddyKit. Questa è la lezione 1 di 3. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Learn Rust Coding, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Learn Rust Coding include 3 lezioni in totale.
Che cos'è FFI?
FFI è l'acronimo di Foreign Function Interface. È un meccanismo che consente a programmi scritti in un linguaggio di programmazione di chiamare funzioni o usare strutture dati definite in un altro linguaggio.
In Rust, FFI consente di interagire con codice scritto in altri linguaggi, soprattutto C. È molto utile per integrare librerie esistenti o API di sistema.
Perché usare FFI?
FFI non è uno strumento di uso quotidiano, ma è potente quando serve:
- Sfruttare librerie C esistenti: Molte librerie mature e ad alte prestazioni sono scritte in C/C++. FFI consente a Rust di usarle direttamente.
- API di sistema: Interagire con funzionalità del sistema operativo che potrebbero disporre solo di interfacce C.
- Interoperabilità: Creare una libreria Rust richiamabile da altri linguaggi, come Python, Java o JavaScript tramite Node.js.
Chiamare C da Rust: dichiarazione
Per chiamare una funzione C da Rust, è innanzitutto necessario dichiararne la firma usando un blocco extern "C". Questo comunica a Rust l'aspetto della funzione C senza fornirne l'implementazione.
La parte "C" specifica la convenzione di chiamata C, assicurando la compatibilità delle chiamate di funzione.
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;
}Chiamare C da Rust: il blocco `unsafe`
La promessa fondamentale di Rust è la sicurezza della memoria. Tuttavia, quando interagisce con codice C tramite FFI, Rust non può garantire la sicurezza del codice esterno.
Per questo motivo, ogni chiamata a una funzione C dichiarata in un blocco extern "C" deve essere racchiusa in un blocco unsafe. Questo segnala al compilatore e agli altri sviluppatori che spetta a Lei garantire il rispetto delle garanzie di sicurezza.
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.");
}Mappatura dei tipi: da Rust a C
Quando si usa l'FFI, è necessario assicurarsi che i tipi Rust corrispondano correttamente ai tipi C. Rust fornisce tipi specifici in std::os::raw e std::ffi a questo scopo.
i32->std::os::raw::c_intf32->std::os::raw::c_floatbool->std::os::raw::c_uchar(o un tipo simile: C non dispone di un tipo booleano standard)&str->*const std::os::raw::c_char(le stringhe C devono essere terminate da null, operazione spesso gestita dastd::ffi::CString)&mut [T]->*mut T
Utilizzate sempre questi tipi C espliciti per evitare un comportamento non definito.
Esempio: chiamare una funzione C `add`
Immaginiamo di avere una libreria C con una funzione int add(int a, int b);. Ecco come chiamarla da Rust. Notate l'uso di c_int per i tipi interi.
(Questo codice illustra la sintassi dell'FFI, ma non verrà eseguito senza una libreria C compilata e collegata esternamente.)
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);
}Esporre Rust a C: nozioni di base
Per rendere una funzione Rust chiamabile da C, sono necessari due elementi:
#[no_mangle]: questo attributo impedisce al compilatore Rust di applicare il "mangling" (modificare) al nome della funzione. I compilatori C si aspettano nomi semplici, senza mangling.extern "C": specifica che la funzione deve usare la convenzione di chiamata C, rendendola compatibile con C.
Esempio: una funzione Rust per C
Ecco una funzione Rust che calcola una somma e che potrebbe essere chiamata da un programma C. Notate gli attributi #[no_mangle] e extern "C".
(Questo codice è pensato per essere compilato come libreria per C, ma include un main per i test interni in questo ambiente.)
#[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);
}Gestione della memoria nell'FFI
La gestione della memoria oltre i confini dell'FFI è fondamentale. Se Rust alloca memoria (ad esempio, una stringa) e passa un puntatore a C, C deve copiare i dati oppure deve essere responsabile del loro corretto rilascio.
Al contrario, se C alloca memoria e passa un puntatore a Rust, Rust non dovrebbe liberarla a meno che non gli venga esplicitamente indicato di farlo; in alternativa, deve copiare i dati.
Strumenti come std::ffi::CString e CStr aiutano a gestire in modo sicuro le stringhe compatibili con C, occupandosi della terminazione null e garantendo il corretto trasferimento della proprietà.
Verifica rapida sull'FFI
Verifichiamo la Sua comprensione della Foreign Function Interface di Rust.
FFI: un ponte tra mondi
Ha imparato a conoscere la Foreign Function Interface di Rust!
L'FFI consente a Rust di offrire una vera interoperabilità, permettendo di:
- Chiamare funzioni dalle librerie C usando
extern "C"e blocchiunsafe. - Esporre funzioni Rust ad altri linguaggi usando
#[no_mangle]epub extern "C". - Gestire con attenzione la corrispondenza dei tipi usando i tipi di
std::os::raw.
L'FFI è uno strumento potente per integrare Rust in ecosistemi diversi, ma ricordi l'importanza di utilizzarlo con attenzione, soprattutto per quanto riguarda la sicurezza e la gestione della memoria!
Domande Frequenti
La lezione «Foreign Function Interface (FFI)» è gratuita?
Sì — il testo completo di «Foreign Function Interface (FFI)» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Learn Rust Coding, passa a CoddyKit PRO. Il corso Learn Rust Coding include 3 lezioni in totale.
Cosa imparerò in «Foreign Function Interface (FFI)»?
Impari a chiamare librerie C da Rust e a esporre funzioni Rust ad altri linguaggi utilizzando FFI per garantire l’interoperabilità. Eserciti Learn Rust Coding con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Learn Rust Coding?
Non è richiesta alcuna esperienza precedente. Learn Rust Coding su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 3.
Quanto tempo richiede la lezione «Foreign Function Interface (FFI)»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Learn Rust Coding?
Sì. Ogni lezione Learn Rust Coding include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Foreign Function Interface (FFI)
- Da Rust a WebAssembly (WASM)
- Benchmark e ottimizzazione delle prestazioni