FFI: Rust ve C Kütüphanelerini Bir Arada Kullanma

  • Konbuyu başlatan Konbuyu başlatan irfo
  • Başlangıç tarihi Başlangıç tarihi

irfo

Moderatör
Top Poster Of Month
Katılım
7 Ocak 2026
Mesajlar
234
Tepkime puanı
2
Puanları
18
Rust'ın en güçlü yanlarından biri, mevcut C kütüphaneleriyle neredeyse sıfır maliyetle (zero-cost) konuşabilmesidir. FFI (Foreign Function Interface), Rust kodunuzun C fonksiyonlarını çağırmasına veya tam tersi şekilde Rust kodunuzun bir C projesinde kullanılmasına olanak tanır.
Bu, "tekerleği yeniden icat etmeden" yıllanmış ve güvenilir C kütüphanelerini (OpenSSL, SQLite, zlib vb.) Rust projelerinize dahil etmenizi sağlar.

1. C Fonksiyonlarını Rust İçinden Çağırmak​

Bir C fonksiyonunu çağırmak için önce Rust'a bu fonksiyonun imzasını (signature) tanıtmanız gerekir. Bunu extern "C" bloğu ile yaparız.

Adım 1: Fonksiyonu Tanımlama​

C tarafında abs (mutlak değer) fonksiyonunu kullanmak istediğimizi varsayalım:
Rust
Kod:
// C standart kütüphanesindeki fonksiyonu tanımlıyoruz
extern "C" {
    fn abs(input: i32) -> i32;
}

fn main() {
    unsafe {
        // Dış dünyadan gelen fonksiyonlar her zaman 'unsafe' kabul edilir
        let sonuc = abs(-42);
        println!("C'den gelen sonuç: {}", sonuc);
    }
}

2. Veri Tiplerini Eşleme: libc Crate​

Rust'taki veri tipleri (örneğin String), C'deki karşılıklarıyla (char*) her zaman aynı bellek dizilimine sahip değildir. Güvenli bir geçiş için libc kütüphanesi kullanılır. libc, C dünyasındaki tiplerin Rust karşılıklarını (c_int, c_char, size_t) sunar.

String Karmaşası​

C stringleri \0 (null) karakteri ile biter. Rust'ta bu geçişi CString (Rust'tan C'ye) ve CStr (C'den Rust'tan) yapıları ile yönetiriz.
Rust
Kod:
use std::ffi::CString;
use std::os::raw::c_char;

extern "C" {
    fn puts(s: *const c_char);
}

fn main() {
    let mesaj = CString::new("C'ye selam gönder!").unwrap();
    unsafe {
        puts(mesaj.as_ptr());
    }
}

3. Rust Kodunu C'ye Açmak (Exporting)​

Rust kodunuzu bir C projesine kütüphane olarak vermek istiyorsanız, Rust derleyicisine bu fonksiyonun ismini değiştirmemesini (mangling) ve C uyumlu bir arayüz sunmasını söylemelisiniz.
Rust
Kod:
#[no_mangle]
pub extern "C" fn rust_topla(a: i32, b: i32) -> i32 {
    a + b
}
Cargo.toml dosyanıza crate-type = ["cdylib"] ekleyerek derlediğinizde, C projelerinin bağlayabileceği (link) bir .so, .dll veya .dylib dosyası elde edersiniz.

4. Bindgen: Otomatik Köprü Oluşturma​

Eğer yüzlerce fonksiyonu olan devasa bir C kütüphanesini içeri aktaracaksanız, bunları tek tek elle yazmak imkansızdır. bindgen aracı, C header dosyalarını (.h) okuyarak otomatik olarak Rust extern bloklarını oluşturur.

5. FFI Kullanırken Altın Kurallar​

KuralNeden?
unsafe KullanımıC tarafındaki bellek yönetiminden Rust sorumlu olamaz.
Panik YönetimiRust kodunuzun C'ye "panik" sızdırmasına izin vermeyin; bu tanımsız davranışa (UB) yol açar. catch_unwind kullanın.
Bellek SahipliğiBelleği kim tahsis ettiyse (allocate), o serbest bırakmalıdır (deallocate). C'de malloc ile ayrılanı Rust'ta drop edemezsiniz.
 
Geri
Üst