Özet - FFI
- Rust kursu
- İleri seviye
- Ders 41/81
- 5 dk
extern, repr(C) ve CString'i birleştirerek C'ye string gönderen wrapper yazarsın.
FFI özeti
C fonksiyonları unsafe extern "C" bloğunda, C türleriyle (c_int, c_char, c_void) bildirilir. Paylaşılan struct'lar #[repr(C)] olmalıdır. Dizeler CString (Rust → C) ve CStr (C → Rust) ile köprülenir. Callback'ler extern "C" fn'dir ve panic sınırı geçemez. Kaynaklar Drop ile, ayıran tarafın fonksiyonuyla serbest bırakılır. Ters yön için #[unsafe(no_mangle)] pub extern "C" fn kullanılır.
C'ye fonksiyon sunmak
Rust'ta yazılmış bir kütüphane C'den ya da başka dillerden (Python, Swift) çağrılabilir. Cargo.toml'da crate-type = ["cdylib"] paylaşılan kütüphane üretir:
#[unsafe(no_mangle)]
pub extern "C" fn rs_topla(a: i32, b: i32) -> i32 {
a + b
}
// C tarafı:
// int32_t rs_topla(int32_t a, int32_t b);Bu fonksiyon Rust içinden normal bir fonksiyon gibi de çağrılabilir; extern "C" fn(i32, i32) -> i32 türünde bir işaretçiye de atanabilir. cbindgen, C başlık dosyasını otomatik üretir.
Uygulama Dışa açılan fonksiyon
Yukarıdaki rs_topla fonksiyonunu yaz. Onu let f: extern "C" fn(i32, i32) -> i32 = rs_topla; ile bir fonksiyon işaretçisine ata ve f(3, 4) sonucunu yazdır.
Başlangıç kodu
fn main() {
// buraya yaz
}Örnek çözüm
#[unsafe(no_mangle)]
pub extern "C" fn rs_topla(a: i32, b: i32) -> i32 {
a + b
}
fn main() {
let f: extern "C" fn(i32, i32) -> i32 = rs_topla;
println!("{}", f(3, 4));
}Beklenen çıktı
7
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 <code>#[no_mangle]</code> ne işe yarar?
- Derleyicinin sembol adını değiştirmesini engeller; C tarafı fonksiyonu adıyla bulur Doğru cevap
- Fonksiyonu gizler
- Inline yapar
- Hata ayıklamayı kapatır
Açıklama: Rust sembol adlarını modül yoluyla kodlar (mangling); dışa açılacak fonksiyonlarda bu kapatılır. Rust 2024'te #[unsafe(no_mangle)] yazılır.
2 Dışa açılan fonksiyon
#[unsafe(no_mangle)]
pub ____ fn rs_topla(a: i32, b: i32) -> i32 {
a + b
}
#[unsafe(no_mangle)]
pub extern "C" fn rs_topla(a: i32, b: i32) -> i32 {
a + b
}
Açıklama: C'den çağrılacak fonksiyon C çağrı kuralıyla tanımlanır.
3 Grubun özeti
| Kavram | Anlamı |
|---|---|
extern "C" { } |
C'yi çağır |
#[repr(C)] |
C düzeni |
CString/CStr |
Dize köprüsü |
#[unsafe(no_mangle)] |
C'ye sun |