0Pricing
Learn Rust Coding · 강의

외부 함수 인터페이스(FFI)

Rust에서 C 라이브러리를 호출하고 FFI를 사용해 Rust 함수를 다른 언어에 공개하여 상호 운용성을 확보하는 방법을 배웁니다.

외부 함수 인터페이스(FFI)은(는) CoddyKit의 무료 Learn Rust Coding 강의입니다. 이것은 3개 중 1번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Learn Rust Coding 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Learn Rust Coding 강의에는 총 3개의 강의가 포함되어 있습니다.

FFI란 무엇인가요?

FFI는 Foreign Function Interface의 약자입니다. 한 프로그래밍 언어로 작성된 프로그램이 다른 언어로 정의된 함수를 호출하거나 자료 구조를 사용할 수 있게 하는 방법입니다.

Rust에서 FFI를 사용하면 다른 언어, 가장 흔하게는 C로 작성된 코드와 상호 작용할 수 있습니다. 기존 라이브러리나 시스템 API를 통합할 때 매우 유용합니다.

FFI를 사용하는 이유

FFI는 일상적으로 사용하는 도구는 아니지만, 다음과 같은 경우에 강력한 기능을 발휘합니다.

  • 기존 C 라이브러리 활용: 성능이 뛰어나고 성숙한 라이브러리 중 상당수가 C/C++로 작성되어 있습니다. FFI를 사용하면 Rust에서 이러한 라이브러리를 직접 사용할 수 있습니다.
  • 시스템 API: C 인터페이스만 제공하는 운영 체제 기능과 상호 작용할 수 있습니다.
  • 상호 운용성: 다른 언어(예: Python, Java 또는 Node.js를 통한 JavaScript)에서 호출할 수 있는 Rust 라이브러리를 만들 수 있습니다.

Rust에서 C 호출하기: 선언

Rust에서 C 함수를 호출하려면 먼저 extern "C" 블록을 사용하여 함수 시그니처를 선언해야 합니다. 이렇게 하면 구현을 제공하지 않고도 C 함수의 형태를 Rust에 알려 줄 수 있습니다.

"C" 부분은 C 호출 규약을 지정하여 함수 호출이 호환되도록 합니다.

extern "C" {
    // Declare C functions here
    // Example: int puts(const char *s);
    fn puts(s: *const std::os::raw::c_char) -> std::os::raw::c_int;
    // Example: int add(int a, int b);
    fn add(a: std::os::raw::c_int, b: std::os::raw::c_int) -> std::os::raw::c_int;
}

Rust에서 C 호출하기: `unsafe` 블록

Rust의 핵심 약속은 메모리 안전성입니다. 그러나 FFI를 통해 C 코드와 상호 작용할 때 Rust는 외부 코드의 안전성을 보장할 수 없습니다.

따라서 extern "C" 블록에서 선언한 C 함수 호출은 반드시 unsafe 블록으로 감싸야 합니다. 이는 안전성 보장을 유지할 책임이 여러분에게 있음을 컴파일러와 다른 개발자에게 알립니다.

extern "C" {
    // We're declaring that a C function `puts` exists.
    fn puts(s: *const std::os::raw::c_char) -> std::os::raw::c_int;
}

fn main() {
    let rust_string = "Hello from Rust via C!";
    // C strings need to be null-terminated.
    let c_string = std::ffi::CString::new(rust_string).expect("CString failed");

    unsafe {
        // Calling the C 'puts' function. This requires 'unsafe'.
        puts(c_string.as_ptr());
    }
    println!("C function call demonstrated.");
}

형식 매핑: Rust에서 C로

FFI를 사용할 때는 Rust 형식이 C 형식에 올바르게 대응하는지 확인해야 합니다. Rust는 이를 위해 std::os::raw와 std::ffi에 전용 형식을 제공합니다.

  • i32 -> std::os::raw::c_int
  • f32 -> std::os::raw::c_float
  • bool -> std::os::raw::c_uchar (또는 이와 유사한 형식. C에는 표준 불리언 형식이 없습니다.)
  • &str -> *const std::os::raw::c_char (C 문자열은 널 종료가 필요하며, 보통 std::ffi::CString이 처리합니다.)
  • &mut [T] -> *mut T

정의되지 않은 동작을 방지하려면 항상 이러한 명시적인 C 형식을 사용하십시오.

예제: C `add` 함수 호출하기

int add(int a, int b); 함수를 포함하는 C 라이브러리가 있다고 가정해 보겠습니다. 다음은 Rust에서 이 함수를 호출하는 방법입니다. 정수 형식에 c_int를 사용하는 점에 유의하십시오.

(이 코드는 FFI 문법을 보여 주기 위한 것이며, 외부에서 컴파일된 C 라이브러리를 연결하지 않으면 실행되지 않습니다.)

extern "C" {
    // Declaration of the C function `add`
    fn add(a: std::os::raw::c_int, b: std::os::raw::c_int) -> std::os::raw::c_int;
}

fn main() {
    let x = 10;
    let y = 20;

    let result = unsafe {
        // Call the C 'add' function within an unsafe block
        add(x as std::os::raw::c_int, y as std::os::raw::c_int)
    };

    println!("Attempted to call C add. Result (if linked): {}", result);
}

C에 Rust 노출하기: 기초

Rust 함수를 C에서 호출할 수 있도록 만들려면 두 가지가 필요합니다.

  1. #[no_mangle]: 이 특성은 Rust 컴파일러가 함수 이름을 "망가뜨리거나"(변경하거나) 변형하지 못하게 합니다. C 컴파일러는 단순하고 변형되지 않은 이름을 기대합니다.
  2. extern "C": 함수가 C 호출 규약을 사용하도록 지정하여 C와 호환되게 합니다.

예제: C에서 사용할 Rust 함수

다음은 합계를 계산하며 C 프로그램에서 호출할 수 있는 Rust 함수입니다. #[no_mangle]과 extern "C" 특성에 주목하십시오.

(이 코드는 C에서 사용할 라이브러리로 컴파일되도록 설계되었지만, 이 환경에서 내부 테스트를 수행하기 위한 main도 포함합니다.)

#[no_mangle]
pub extern "C" fn rust_add_and_print(
    a: std::os::raw::c_int,
    b: std::os::raw::c_int
) -> std::os::raw::c_int {
    let sum = a + b;
    println!("Rust function received: {} + {} = {}", a, b, sum);
    sum
}

fn main() {
    println!("This Rust code exposes a function for C.");
    // We can also call it internally for demonstration
    let result = rust_add_and_print(5, 7);
    println!("Internal call result: {}", result);
}

FFI 메모리 관리

FFI 경계를 넘나드는 메모리 관리는 매우 중요합니다. Rust가 메모리(예: 문자열)를 할당하고 포인터를 C에 전달하면, C는 데이터를 복사하거나 메모리를 올바르게 해제할 책임을 져야 합니다.

반대로 C가 메모리를 할당하고 포인터를 Rust에 전달한 경우, Rust는 명시적으로 지시받지 않는 한 해당 메모리를 해제해서는 안 되며, 그렇지 않으면 데이터를 복사해야 합니다.

std::ffi::CString 및 CStr과 같은 도구는 널 종료를 처리하고 소유권을 올바르게 이전하여 C와 호환되는 문자열을 안전하게 관리하도록 도와줍니다.

FFI 빠른 확인

Rust의 Foreign Function Interface에 대한 이해도를 확인해 보겠습니다.

FFI: 세계를 연결하는 다리

Rust의 Foreign Function Interface를 배웠습니다!

FFI를 사용하면 Rust는 진정한 상호 운용성의 강자가 되어 다음과 같은 작업을 수행할 수 있습니다.

  • extern "C"와 unsafe 블록을 사용하여 C 라이브러리의 함수를 호출합니다.
  • #[no_mangle]과 pub extern "C"를 사용하여 다른 언어에 Rust 함수를 노출합니다.
  • std::os::raw 형식을 사용하여 형식 매핑을 신중하게 처리합니다.

FFI는 Rust를 다양한 생태계에 통합하는 강력한 도구입니다. 하지만 특히 안전성과 메모리 관리 측면에서 신중하게 사용해야 한다는 점을 기억하십시오!

자주 묻는 질문

“외부 함수 인터페이스(FFI)” 강의는 무료인가요?

네 — “외부 함수 인터페이스(FFI)” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Learn Rust Coding 강의 전체를 잠금 해제할 수 있습니다. Learn Rust Coding 강의에는 총 3개의 강의가 포함되어 있습니다.

“외부 함수 인터페이스(FFI)”에서 뭘 배우나요?

Rust에서 C 라이브러리를 호출하고 FFI를 사용해 Rust 함수를 다른 언어에 공개하여 상호 운용성을 확보하는 방법을 배웁니다. 브라우저에서 직접 실행하는 실습 코드로 Learn Rust Coding을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Learn Rust Coding을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Learn Rust Coding은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 3개 중 1번째 강의입니다.

“외부 함수 인터페이스(FFI)” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Learn Rust Coding 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Learn Rust Coding 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 외부 함수 인터페이스(FFI)
  2. Rust에서 WebAssembly(WASM)로
  3. 벤치마킹과 성능 조정
← Learn Rust Coding(으)로 돌아가기