unsafe 를 쓰는 제일 흔한 이유가 FFI — Foreign Function Interface, Rust 가 C 라이브러리랑 운영체제 API 에 말 거는 법이야. 다른 언어로 쓰인 기존 코드베이스에 Rust 가 끼어드는 법이기도 해.
Rust 에서 C 호출
extern "C" 블록이 C 라이브러리의 함수를 선언해; 그걸 호출하는 게 unsafe 야, 컴파일러가 외부 코드가 Rust 보장을 지키는지 검증 못 하니까. 시그니처를 선언하고, 라이브러리를 링크하고, 호출을 감싸 — 보통 입출력을 검증하는 safe Rust 함수로 해서 호출자가 raw FFI 를 안 건드리게.
왜 FFI 가 중요하냐
수십 년 검증된 C 랑 시스템 라이브러리가 있어; FFI 가 재작성 없이 Rust 가 그걸 쓰게 해. 반대로도 돼 — Rust 가 C, Python, FFI 가능한 아무 언어가 부르는 C 호환 API 를 노출할 수 있어. 이 양방향 다리가 Rust 가 점진적으로 채택되는 이유야: Rust 로 재작성한 hot 모듈 하나가 큰 C 나 Python 코드베이스에 끼어들 수 있어.
unsafe extern 레이어, 위에 safe 한 관용적 Rust API 를 가져. unsafe 경계를 한 번 감사하고; 크레이트 쓰는 모두가 safe Rust 에 머물러. objc2 계열 크레이트가 macOS 시스템 API 에 정확히 이걸 해.macOS 예시
구체적 경우: macOS 에서 창을 앞으로 가져오는 게 가끔 Cocoa 의 NSApplication.activate() 호출이 필요해 — pure-Rust 등가물이 없는 시스템 API. objc2 계열 크레이트가 그 Objective-C FFI 를 safe Rust 인터페이스로 감싸. Cinder 의 네이티브 코어가 정확히 이 패턴을 써: macOS 전용 능력에 닿는 작고 감사된 FFI 레이어를, 나머지 앱엔 평범한 safe Rust 로 노출. 그게 FFI 가 진짜 일을 하는 거야 — 다른 데 안전을 다 내주지 않고 플랫폼에 닿기.