[Rust] FFI: C 정적 라이브러리 땡겨쓰기 - 함수

Rust에서는 FFI(Foreign Function Interface)라는 것을 통해 C/C++로 작성된 라이브러리를 사용할 수 있다.

먼저 테스트용 라이브러리를 간단하게 만들어보자.

정수 덧셈만 해주는 간단한 코드다.

그리고 gcc로 정적 라이브러리 파일을 만든다.

그럼 이걸 이제 테스트할 프로젝트 폴더로 옮긴다.

이제 코드를 짜보자.
기본적으로 Rust는 타입시스템이라든가 전체적인 구조가 C와 완전히 다르다.
그래서 C와 연동하려면 기본적인 정수 타입을 표시하는데도 어려움이 따른다.
이를 해결하려면 libc 크레이트를 사용하면 된다.

의존성에 libc를 추가해준다.

이제 진짜 코드를 보자

extern crate libc;
use libc::c_int;

#[link(name="libadd", kind="static")]
extern
{
    fn add(_: c_int, _: c_int)->c_int;
}

fn main()
{
    let result = unsafe{ add(10, 20) };
    println!("{}", result);
}

일단 libc를 포함하고, C의 정수타입을 표현할 c_int를 use한다.

그리고 extern 중괄호 필드를 펼치는데, 여기서 땡겨올 C 라이브러리에 대한 프로토타입을 표시한다.
이게 일종의 헤더파일의 역할을 하는 것이다.

링크할 라이브러리 관련 사항은 #[link()] 매크로로 설정한다.
name은 링크할 라이브러리의 이름이다. 아까 만들었던대로 libadd로 넣고...
kind는 동적 라이브러리인지, 정적 라이브러리인지 등을 선택한다. 정적 라이브러리로 해놨으니 static으로 해준다.

나머지는 별거 없다.
extern 필드 함수 선언에선 함수 인자의 이름도 사용하도록 하는데, 신경쓰기 싫다면 그냥 _로 비워두면 된다.

그리고 extern한 외부 함수의 사용은 unsafe 블럭에서만 가능하니, 호출부만 따로 저렇게 묶어준다,


그럼 대충 이렇게 잘 돌 것이다.

이 경우에는 코드나 인터페이스가 굉장히 간단하기 때문에 고려할 것이 별로 없지만,
본격적으로 사용한다면 충돌을 빚을 일이 더욱 많을 것이다.


참조
https://doc.rust-lang.org/nomicon/ffi.html