Rust 라이브러리를 위한 멀티 언어 FFI 자동 생성 도구
Rust 라이브러리를 여러 언어에서 쉽게 사용할 수 있도록 FFI 바인딩을 자동 생성하는 'Diplomat' 소개
기존 도구의 한계를 극복하기 위해 단방향(Unidirectional) FFI에 집중하여 설계됨
코드 생성 방식은 Rust 코드 내 브릿지(Bridge) 코드를 기반으로 함
다양한 언어 지원 및 확장성을 목표로 하며, 커뮤니티 기여를 장려함
단방향(Unidirectional) FFI 설계의 이점
커뮤니티에서는 Diplomat의 단방향 FFI(Unidirectional FFI) 설계가 핵심적인 차별점이라고 분석합니다. 이는 특정 언어에 종속되지 않고 Rust 라이브러리를 여러 언어(C++, JS, Dart, Kotlin, Python 등)로 확장하는 데 유리하다는 평가입니다. 기존 양방향(Bidirectional) 도구들은 특정 언어 쌍에 최적화되어 있어 범용성이 떨어진다는 지적이 있습니다. Diplomat은 API 정의를 Rust 라이브러리에 두어 일관성을 유지합니다.
코드 생성 및 브릿지(Bridge) 코드의 역할
논의에 따르면, Diplomat은 Rust 코드 내 `#[diplomat::bridge]` 속성으로 표시된 브릿지(Bridge) 코드를 기반으로 extern "C" API를 생성합니다. 이 방식은 코드 변경의 영향 범위를 제한하여 FFI 레이어의 예기치 않은 변경을 방지합니다. 또한, 브릿지 코드는 FFI에 특화된 Rust 문법만 사용하도록 제한하여 복잡성을 줄이고, 기존 Rust API 사용자에게는 영향을 주지 않도록 설계되었습니다.
다국어 지원 및 확장성 확보 전략
참여자들은 Diplomat의 언어 확장성(Extensibility)에 주목합니다. 새로운 언어에 대한 바인딩 생성을 위해 별도의 '백엔드(Backend)'를 개발하는 방식으로, ICU4X 팀이 아닌 외부 기여(Kotlin, Python 백엔드)로 기능이 확장된 사례를 언급합니다. 이는 개별 백엔드에서 특정 기능 지원 여부를 선택할 수 있게 하여, 모든 언어에 대한 동시 지원 부담을 줄여줍니다.
라이프타임(Lifetime) 처리의 복잡성
글에서는 Rust의 라이프타임(Lifetime) 개념을 GC 언어(JS, Dart 등)로 전달할 때 발생하는 문제를 다룹니다. Rust의 참조(&)는 컴파일 타임에 소멸 시점을 보장하지만, GC 언어에서는 이를 직접 적용하기 어렵습니다. Diplomat은 이를 해결하기 위해 '라이프타임 에지(Lifetime Edge)' 개념을 도입하여, 반환된 객체가 원본 객체보다 오래 살아남더라도 원본 객체를 GC로부터 보호하는 메커니즘을 사용한다고 설명합니다.
기존 도구(uniffi, BoltFFI)와의 비교
커뮤니티에서는 Diplomat과 유사한 기능을 제공하는 uniffi 및 BoltFFI를 비교합니다. uniffi는 IDL 선택지를 제공하며, BoltFFI는 패키징에 강점을 보인다고 언급됩니다. 하지만 Diplomat은 Rust 코드 자체에서 인터페이스를 명시하는 방식과 단방향 FFI에 집중한 설계로 차별점을 가진다고 분석합니다. 이러한 허브 앤 스포크(Hub-and-Spoke) 모델은 라이브러리 개발에 적합하다는 평가입니다.