[Rust] FFI: pyo3 - Python에 Rust 코드 연동하기
파이썬은 여러모로 타 언어들에 종속적인 언어라 할수있다.
태생적인 성능문제 때문에 어느정도 성능이 요구되는 모듈은 태반이 C/C++로 작성되기 때문이다.
근데 아무래도 C/C++는 여러모로 불편한 점이 많다보니... 대안으로 Rust도 사용해볼만하다고 본다.
한번 rust로 모듈을 짜서 python에서 사용하는 방법을 다뤄보도록 하겠다.
가장 정통적인 방법을 추구한다면 그냥 rust에서 C FFI로 동적 라이브러리를 뽑아서 파이썬에서 사용하는 것이겠지만, 여기서는 좀더 편리한 방법을 사용해보도록 하겠다.
준비물
Rust와 Python이 당연히 깔려있어야 한다.
버전 최소 요구사항은 CPython 3.7, Rust 1.48다.
OS는 Linux나 Mac인 편이 좋다. windows는 좀 많이 불편하거나 잘 안될 수 있다.
Rust 코드 작성
먼저 Cargo.toml은 다음과 같이 해둔다.
종속성은 pyo3 뿐이면 된다. 그리고 동적 라이브러리로 빌드할 수 있도록 lib 구성을 적절해 해둔다.
[package]
name = "pyrust"
version = "0.1.0"
authors = ["sssan"]
edition = "2021"
[lib]
name = "pyrust"
crate-type = ["cdylib"]
[dependencies]
pyo3 = { version = "0.18.2", features = ["extension-module"] }
여기서 [lib].name이 파이썬 모듈명이 된다.
코드는 다음과 같이 작성하면 된다.
use pyo3::prelude::*;
#[pyfunction]
pub fn sum(nums: Vec<i64>) -> PyResult<i64> {
let sum = nums.iter().sum();
Ok(sum)
}
#[pymodule]
pub fn pyrust(_python: Python, module: &PyModule) -> PyResult<()> {
module.add_function(wrap_pyfunction!(sum, module)?)?;
Ok(())
}
pyfunction 매크로를 통해 함수를 정의하고, 그걸 pymodule 매크로가 달린 함수로 추가해준다.
pymodule가 붙은 함수는 이 파이썬 모듈 자체를 나타내는 함수가 되고, 함수명은 모듈명과 완전히 일치해야 한다. 다르면 모듈이 제대로 뽑히질 않는다.
아무튼 그래서 배열을 받아서 합산해주는 함수를 만들어봤다.
Python에서 사용하기
먼저 maturin라는 전용 도구를 설치해야 한다.
pip install maturin


그리고 가상 환경(virtual environment)를 설정한다.
python -m venv .env
source .env/bin/activate

그럼 이런 디렉터리가 생길텐데,
여기다가 직접 말아놓은 파이썬 모듈을 넣어놓고 import할 수 있게 하는 식으로 사용하는 것이다.
그리고 develop 명령을 사용하면
maturin develop

모듈을 말아서 저기다가 넣어준다.
그럼 파이썬에서 바로 import로 꺼내쓸 수 있게 되는 것이다.

잘 된다.
crate를 릴리즈 모드로 빌드하려면 -r 옵션을 사용한다.

이외에도 그냥 빌드만 해서 사용하려면 build 명령만 사용하면 되고, 저걸 pypi에 올려서 쓴다거나 하려면 publish 명령을 사용하면 된다.
그렇다.