외부 함수 인터페이스
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)
}
}
}