FFI
이 문서는 Wave 언어에서 외부에 구현된 함수를 호출하기 위한 FFI(외부 함수 인터페이스) 규격을 설명합니다. FFI를 통해 Wave 프로그램은 다른 언어로 작성된 네이티브 라이브러리와 직접 연동할 수 있습니다.
개요
Wave의 FFI는 선언 기반으로 동작합니다. 외부 함수는 Wave 코드에서 구현하지 않으며, 해당 함수가 어떤 ABI(Application Binary Interface)를 따르는지만 명시합니다. 실제 구현은 링크 단계에서 외부 라이브러리로부터 해결됩니다.
FFI는 컴파일 타임에 함수의 존재만을 선언하고, 실행 파일 생성 시 링커가 실제 심볼을 연결하는 방식으로 동작합니다.
extern 선언
외부 함수는 extern 키워드를 사용하여 선언합니다. 모든 외부 함수 선언에는 ABI 지정이 반드시 필요합니다.
extern(abi) fun 함수명(인자들...) -> 반환타입;
ABI 지정
extern 선언에는 반드시 ABI를 명시해야 합니다.
ABI는 외부 함수가 어떤 호출 규약과 심볼 규칙을 따르는지를 나타냅니다.
extern(c) fun printf(fmt: ptr<u8>);
extern(rust) fun rust_func(i32);
ABI는 식별자로 취급되며, 언어 차원에서 특정 ABI를 기본값으로 제공하지 않습니다. 모든 외부 함수는 명시적으로 ABI를 지정해야 합니다.
함수 단위 extern 선언
외부 함수 하나를 선언할 경우 다음과 같이 작성합니다.
extern(c) fun InitWindow(width: i32, height: i32, title: ptr<u8>);
이 선언은 C ABI를 따르는 InitWindow 심볼이 외부 라이브러리에 존재함을 의미합니다.
블록 단위 extern 선언
동일한 ABI를 사용하는 외부 함수가 여러 개일 경우, 블록 형태로 묶어 선언할 수 있습니다.
extern(c) {
fun InitWindow(width: i32, height: i32, title: ptr<u8>);
fun CloseWindow();
fun BeginDrawing();
fun EndDrawing();
}
블록 단위 선언은 함수 단위 선언과 의미적으로 완전히 동일하며, 단순히 가독성과 구조화를 위한 문법입니다.
심볼 이름 지정
일부 ABI에서는 Wave 함수 이름과 실제 링커 심볼 이름이 일치하지 않을 수 있습니다. 이 경우, 외부 함수가 연결될 실제 심볼 이름을 문자열로 명시할 수 있습니다.
함수 단위 심볼 지정
extern(rust, "_ZN4test10rust_func117h123abcE")
fun rust_func(i32);
이 선언은 rust_func 호출 시 _ZN4test10rust_func117h123abcE 심볼을 사 용하도록 지정합니다.
블록 단위 심볼 지정
블록 단위 선언에서는 각 함수 뒤에 심볼 이름을 개별적으로 지정할 수 있습니다.
extern(rust) {
fun rust_func1(i32) "_ZN4test10rust_func117h123abcE";
fun rust_func2(i32) "_ZN4test10rust_func217h456defE";
}