CodeBlanks Logo Icon CodeBlanks

Özet - FFI

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

main.rs
fn main() {
    // buraya yaz
}

Örnek çözüm

main.rs
#[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

Soru
#[unsafe(no_mangle)]
pub ____ fn rs_topla(a: i32, b: i32) -> i32 {
    a + b
}
Cevap
#[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

İleri seviye bölümündeki tüm dersler