Rust와 PyO3를 이용한 파이썬 C/C++ 라이브러리 호출하기

Rust는 안전성, 속도 및 병렬성을 고려한 시스템 프로그래밍 언어입니다. Rust는 C/C++보다 안정성 면에서 우수하며, 파이썬의 프로젝트에서도 유용하게 사용될 수 있습니다. PyO3는 Rust를 이용하여 만든 파이썬 확장을 작성할 수 있는 라이브러리입니다. 이 블로그 포스트에서는 Rust와 PyO3를 사용하여 파이썬에서 C/C++ 라이브러리를 호출하는 방법에 대해 알아보겠습니다.

1. Rust 프로젝트 생성하기

Rust로 C/C++ 라이브러리를 호출하기 위해서는 Rust 프로젝트를 먼저 생성해야 합니다. 다음은 Rust 프로젝트를 생성하는 명령어입니다.

$ cargo new my_project

위 명령어를 실행하면 my_project라는 이름의 Rust 프로젝트가 생성됩니다.

2. PyO3 설치하기

PyO3를 설치하기 위해서는 해당 프로젝트의 Cargo.toml 파일에 PyO3 종속성을 추가해야 합니다. 다음은 Cargo.toml 파일에 PyO3 종속성을 추가하는 예시입니다.

[dependencies]
pyo3 = { version = "0.15", features = ["extension-module"] }

위와 같이 Cargo.toml 파일에 종속성을 추가한 후, 다음 명령어를 실행하여 PyO3를 설치합니다.

$ cargo build

3. Rust 코드 작성하기

Rust로 C/C++ 라이브러리를 호출하기 위해서는 Rust 코드를 작성해야 합니다. 다음은 Rust 프로젝트의 src/lib.rs 파일에 Rust 코드를 작성하는 예시입니다.

use pyo3::prelude::*;

#[pymodule]
fn my_module(py: Python, m: &PyModule) -> PyResult<()> {
    // C/C++ 라이브러리 호출 코드 작성
    // ...

    Ok(())
}

#[pymodule]
fn rust_library(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_module::<my_module>()?;

    Ok(())
}

#[pymodule]
fn my_project(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_module::<rust_library>()?;

    Ok(())
}

#[pymodule]
fn my_library_py(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_module::<my_project>()?;

    Ok(())
}

#[pymodule]
fn my_library(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_module::<my_library_py>()?;

    Ok(())
}

// PyO3 모듈 초기화
#[pymodule]
fn my_library_rust(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_module::<my_library>()?;

    Ok(())
}

#[pymodule]
fn _my_library(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_module::<my_library_rust>()?;

    Ok(())
}

#[pymodule]
fn my_library_pybynative(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add("my_native_function", py_fn!(my_native_function))?;

    Ok(())
}

#[pymodule]
fn my_library_native(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_module::<my_library_pybynative>()?;

    Ok(())
}

#[pymodule]
fn _my_library_native(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_module::<my_library_native>()?;

    Ok(())
}

/// Python에서 호출할 함수
#[pyfunction]
fn my_native_function(_py: Python, arg: usize) -> usize {
    // C/C++ 라이브러리 호출 함수 정의
    // ...

    arg * 2
}

/// Rust에서 파이썬 확장 모듈을 생성하는 함수
#[pymodule]
fn my_extension_module(py: Python, m: &PyModule) -> PyResult<()> {
    m.add_function(wrap_pyfunction!(my_native_function, m)?)?;

    Ok(())
}

/// PyO3 초기화 함수
#[pymodule]
fn my_module_initializer(py: Python, m: &PyModule) -> PyResult<()> {
    m.add_function(wrap_pyfunction!(my_extension_module, m)?)?;

    Ok(())
}

/// PyO3 모듈 정의
#[pyclass(subclass)]
#[derive(Debug)]
struct MyModule {}
#[pymethods]
impl MyModule {
    #[new]
    #[args(kwargs = "**")]
    fn new(kwargs: Option<&PyDict>) -> PyResult<Self> {
        let wrap = Python::with_gil(|py| {
            my_module_initializer(py, m)?;
            my_module.weather_init()?;
            my_module.rust_library_init()?;
            my_module.my_module_init()?;
            my_module.my_project_init()?;
            my_module.my_library_init()?;
            my_module.my_library_py_init()?;
            my_module.my_library_rust_init()?;
            my_module._my_library_init()?;
            my_module.my_library_native_init()?;
            my_module._my_library_native_init()?;
            my_module.my_library_pybynative_init()?;

            Ok(())
        });
        Ok(Self { py_module: wrap })
    }
}

/// 모듈 초기화 함수
#[no_mangle]
pub extern "C" fn PyInit_my_module() -> *mut pyo3::ffi::PyObject {
    let wrap = pyo3::types::IntoPy::into_py(Some(pyo3::types::Borrow::Borrowed(Python::acquire_gil().python())), pyo3::types::PyAny::new(MyModule::new(None).unwrap())) as *mut pyo3::ffi::PyObject;
    wrap
}

위 코드는 Rust로 작성된 C/C++ 라이브러리를 호출하기 위한 예시 코드입니다. 필요한 C/C++ 라이브러리 호출 코드를 작성해 주세요.

4. PyO3를 이용한 라이브러리 호출

Rust 코드가 작성되었다면, PyO3를 사용하여 파이썬에서 Rust 코드를 호출할 수 있습니다. 다음은 파이썬에서 Rust 라이브러리를 호출하는 예시입니다.

import my_library_native

result = my_library_native.my_native_function(10)
print(result)

Rust와 PyO3를 이용하여 파이썬에서 C/C++ 라이브러리를 호출하는 방법을 알아보았습니다. Rust와 PyO3를 사용하면 파이썬 프로젝트에서 안정성과 속도를 향상시킬 수 있습니다.

References:

#Rust #PyO3