Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

외부 함수 인터페이스

Rust는 C 라이브러리에 대한 외부 함수 인터페이스(Foreign Function Interface, FFI)를 제공합니다. 외부 함수는 외부 라이브러리의 이름이 포함된 #[link] 속성이 달린 extern 블록 내에 선언되어야 합니다.

use std::fmt;

// 이 extern 블록은 libm 라이브러리에 링크됩니다
#[cfg(target_family = "windows")]
#[link(name = "msvcrt")]
extern {
    // 이는 단정도 복소수의 제곱근을 계산하는
// 외부 함수입니다
    fn csqrtf(z: Complex) -> Complex;

    fn ccosf(z: Complex) -> Complex;
}
#[cfg(target_family = "unix")]
#[link(name = "m")]
extern {
    // 이는 단정도 복소수의 제곱근을 계산하는
// 외부 함수입니다
    fn csqrtf(z: Complex) -> Complex;

    fn ccosf(z: Complex) -> Complex;
}

// 외부 함수를 호출하는 것은 안전하지 않은(unsafe) 것으로 간주되므로,
// 이를 감싸는 안전한 래퍼(wrapper)를 작성하는 것이 일반적입니다.
fn cos(z: Complex) -> Complex {
    unsafe { ccosf(z) }
}

fn main() {
    // z = -1 + 0i
    let z = Complex { re: -1., im: 0. };

    // 외부 함수를 호출하는 것은 안전하지 않은(unsafe) 작업입니다
    let z_sqrt = unsafe { csqrtf(z) };

    println!("{:?}의 제곱근은 {:?}입니다", z, z_sqrt);

    // unsafe 연산을 감싼 안전한 API 호출
    println!("cos({:?}) = {:?}", z, cos(z));
}

// 단정밀도 복소수의 최소 구현
#[repr(C)]
#[derive(Clone, Copy)]
struct Complex {
    re: f32,
    im: f32,
}

impl fmt::Debug for Complex {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if self.im < 0. {
            write!(f, "{}-{}i", self.re, -self.im)
        } else {
            write!(f, "{}+{}i", self.re, self.im)
        }
    }
}