Cod Unsafe și Interoperabilitate FFI în Rust: Raw Pointers (*const T, *mut T) și extern „C” în Rust

Ghid complet pentru programarea Unsafe și interoperabilitatea FFI în Rust: cele 5 superputeri din blocurile unsafe, manipularea pointerilor cruzi (*const T, *mut T) și crearea de abstracțiuni sigure peste biblioteci C.

Sintaxă
unsafe { *ptr = 42; } | extern "C" { fn malloc(size: usize) -> *mut c_void; }

Filosofia limbajului Rust nu este de a interzice operațiunile de nivel scăzut, ci de a forța delimitarea strictă a codului nesigur. Cuvântul cheie unsafe nu dezactivează Borrow Checker-ul și nu anulează sistemul de tipuri; el îi semnalează compilatorului că dezvoltatorul preia manual responsabilitatea garantării invarianților de memorie pentru 5 operațiuni specifice.

Cele 5 „Superputeri” Unsafe

  1. Dereferențierea pointerilor cruzi (Raw Pointers: *const T și *mut T).
  2. Apelarea funcțiilor sau metodelor declarate unsafe (inclusiv funcții externe C via FFI).
  3. Implementarea trait-urilor marcate ca unsafe (cum sunt Send și Sync).
  4. Modificarea variabilelor statice mutabile (static mut).
  5. Accesarea câmpurilor dintr-o uniune C (union).
Construirea unei Abstracțiuni Sigure peste Pointeri Cruzi
// Funcție complet sigură (Safe Rust) care ascunde intern un bloc unsafe:
pub fn interschimba_valori(stanga: &mut T, dreapta: &mut T) {
    // Verificăm dacă referințele nu indică spre exact aceeași adresă de memorie:
    let ptr_stanga = stanga as *mut T;
    let ptr_dreapta = dreapta as *mut T;

    if ptr_stanga != ptr_dreapta {
        // În interiorul blocului unsafe operăm direct pe adrese fizice:
        unsafe {
            // std::ptr::swap realizează un schimb de memorie pe bază de memcpy:
            std::ptr::swap(ptr_stanga, ptr_dreapta);
        }
    }
}

// Interoperabilitate cu o funcție nativă din biblioteca standard C (libc):
extern "C" {
    // Declarăm semnătura funcției din sistem:
    fn puts(sir: *const libc::c_char) -> libc::c_int;
}

pub fn afiseaza_mesaj_c() {
    let text = std::ffi::CString::new("Apel nativ C din Rust!").unwrap();
    unsafe {
        puts(text.as_ptr());
    }
}

Regula de Aur a Dezvoltării Enterprise în Rust

Păstrați întotdeauna suprafața de cod unsafe la un minim absolut (ideal <1% din baza de cod) și încapsulați-o întotdeauna într-un API 100% sigur (Safe Wrapper). Dacă o funcție publică nu este marcată cu unsafe, ea nu trebuie să poată provoca sub nicio formă Undefined Behavior (corupere de memorie, segfault), indiferent de argumentele transmise de utilizator!