Rust как клей: Интеграция с Python, C и другими языками

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Rust как универсальный клей: почему интеграция с другими языками — это суперсила

Вы когда-нибудь мечтали написать высокопроизводительный модуль на Rust, но не хотели переписывать весь проект на Python? Или, может быть, вам нужно добавить безопасную работу с памятью в старую C-библиотеку? Добро пожаловать в мир интеграции Rust с другими языками. Здесь Rust выступает не просто как самостоятельный язык, а как мощный "клей", который соединяет экосистемы.

На pythonlib.ru мы часто говорим о Python, но сегодня сделаем крутой поворот. Rust — это не только скорость и безопасность, но и невероятная гибкость. Он умеет интегрироваться с Python через PyO3, вызывать C-функции через FFI, и даже компилироваться в WebAssembly для браузера. В этой статье мы разберем три главных сценария, покажем реальный код и дадим практические советы. Поехали!

Зачем интегрировать Rust с другими языками?

Представьте: у вас есть огромный проект на Python, который тормозит из-за циклов. Вы можете переписать критический участок на Rust, получить прирост скорости в 10-100 раз и при этом не трогать остальной код. Или вы работаете с legacy C-библиотекой и хотите обернуть её в безопасный Rust-интерфейс. Rust для этого идеален благодаря Foreign Function Interface (FFI).

Основные причины для интеграции:

  • Производительность — Rust быстрее Python и JavaScript в вычислительных задачах.
  • Безопасность — Rust защищает от утечек памяти и гонок данных, что критично для C/C++.
  • Экосистема — вы получаете доступ к библиотекам Rust, не покидая родной язык.
  • WebAssembly — Rust-код работает в браузере с почти нативной скоростью.

Интеграция Rust с Python через PyO3

PyO3 — это самый популярный способ связать Rust и Python. Вы пишете функции на Rust, компилируете их в нативный модуль (.so или .pyd) и импортируете как обычный Python-модуль. Звучит магически? На деле — просто.

Установка и настройка

Для начала установите maturin — инструмент для сборки Rust-расширений Python:

pip install maturin

Создайте новый проект:

maturin init --bindings pyo3

Это создаст структуру с файлом Cargo.toml и lib.rs.

Пример: ускорение вычислений

Допустим, нам нужно быстро посчитать числа Фибоначчи. На Python это может быть медленно, а на Rust — молниеносно. Вот код в src/lib.rs:

use pyo3::prelude::*;

#[pyfunction]
fn fibonacci(n: u32) -> u64 {
    match n {
        0 => 0,
        1 => 1,
        _ => fibonacci(n - 1) + fibonacci(n - 2),
    }
}

#[pymodule]
fn rust_fib(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_function(wrap_pyfunction!(fibonacci, m)?)?;
    Ok(())
}

Собираем модуль:

maturin develop

Теперь в Python:

import rust_fib
print(rust_fib.fibonacci(40))  # 102334155

Сравните скорость с чистым Python — разница будет в десятки раз! Это идеальный пример интеграции Rust с Python для оптимизации.

Передача сложных данных

PyO3 поддерживает не только числа, но и списки, словари и даже numpy-массивы. Например, можно передать список и обработать его на Rust:

#[pyfunction]
fn sum_list(numbers: Vec<i32>) -> i32 {
    numbers.iter().sum()
}

В Python:

print(rust_fib.sum_list([1, 2, 3, 4]))  # 10

Это открывает огромные возможности для интеграции Rust с Python в data science и веб-разработке.

Rust и C: классический FFI

Rust создавался как замена C/C++, поэтому FFI Rust — это его родная стихия. Вы можете вызывать C-функции из Rust и наоборот. Это полезно для работы с системными библиотеками (например, libcurl, OpenSSL) или для постепенной миграции кода.

Вызов C из Rust

Предположим, у нас есть C-функция, которая складывает два числа:

// add.c
int add(int a, int b) {
    return a + b;
}

Компилируем в динамическую библиотеку:

gcc -shared -o libadd.so -fPIC add.c

Теперь вызываем её из Rust:

// main.rs
extern "C" {
    fn add(a: i32, b: i32) -> i32;
}

fn main() {
    unsafe {
        let result = add(5, 7);
        println!("Result from C: {}", result); // 12
    }
}

Обратите внимание на unsafe — Rust требует явного указания, что мы работаем с небезопасным кодом. Это часть философии безопасности языка.

Экспорт Rust-функций в C

Можно и наоборот: написать функцию на Rust и использовать её в C-проекте. Для этого используем #[no_mangle] и extern "C":

#[no_mangle]
pub extern "C" fn multiply(a: i32, b: i32) -> i32 {
    a * b
}

Компилируем в библиотеку:

cargo build --release

Затем подключаем её в C:

#include <stdio.h>
extern int multiply(int a, int b);

int main() {
    printf("%d\n", multiply(3, 4)); // 12
    return 0;
}

Это классический пример интеграции Rust с C, который используется в embedded-системах и операционных системах.

Rust и WebAssembly: браузерная мощь

Хотите запустить Rust-код в браузере? WebAssembly (Wasm) — это ваш выбор. Rust компилируется в Wasm, который работает в любом современном браузере. Это идеально для игр, графики и высоконагруженных веб-приложений.

Инструмент wasm-pack

Установите wasm-pack:

cargo install wasm-pack

Создайте проект:

cargo new --lib rust_wasm
cd rust_wasm

Добавьте в Cargo.toml:

[lib]
crate-type = ["cdylib"]

[dependencies]
wasm-bindgen = "0.2"

Теперь напишем функцию, которая

Блоги

Рекомендаций по книгам