跨语言编程:Python与Rust的互操作实现
Python与其他编程语言的交互方法
- 通过FFI(外部函数接口)实现调用,在Java中称为JNI,将Rust/Go/C/C++编译为C兼容的动态库,然后利用Python的ctypes模块进行加载和调用
- 采用进程间通信机制(如基于socket的通信)
- 通过网络协议进行交互,例如RPC框架、HTTP RESTful API等
- 借助虚拟机/解释器/中间层进行桥接,如Jython实现Python调用Java,PyExecJS执行JavaScript代码
- 利用WebAssembly(WASM)作为中间层进行语言间通信
构建Rust动态链接库
将Rust代码编译为C兼容的动态链接库,供Python通过ctypes模块加载并调用函数
- 使用cargo创建新的Rust库项目
cargo new mathlib --lib
- 打开mathlib项目,修改Cargo.toml文件,添加库配置选项 Cargo.toml
...
[lib]
name = "mathlib"
crate-type = ["cdylib"]
- 在src/lib.rs中实现导出函数 src/lib.rs
use std::ffi::{CStr, CString};
use std::os::raw::c_char;
#[no_mangle]
pub extern "C" fn calculate_sum(a: i32, b: i32) -> i32 {
a + b
}
#[no_mangle]
pub extern "C" fn compute_sum_float(x: f32, y: f32) -> f32 {
x + y
}
#[no_mangle]
pub extern "C" fn concat_strings<'a>(first: *const c_char, second: *const c_char) -> *mut c_char {
let first_str = unsafe {CStr::from_ptr(first)};
let first_text = first_str.to_str().expect("Invalid UTF-8 string");
let second_str = unsafe {CStr::from_ptr(second)};
let second_text = second_str.to_str().expect("Invalid UTF-8 string");
let combined = String::from(first_text) + &String::from(second_text);
let result = CString::new(combined).expect("Failed to create CString").into_raw();
result
}
关键说明:
#[no_mangle]属性告诉Rust编译器不要改变函数的原始名称pub extern "C"声明将函数以C语言风格导出,供外部调用- 字符串处理流程:
*c_char→CStr→&str→String→CString→*c_char
- 编译为动态链接库 在项目根目录执行构建命令
cargo build --release
编译完成后,在target/release目录下会生成对应操作系统的动态链接库:libmathlib.so( Linux)、libmathlib.dylib( macOS)或mathlib.dll( Windows)
- Python调用动态链接库示例 invoke_rust.py
import ctypes
import sys
# 加载动态链接库
try:
lib = ctypes.CDLL("./target/release/libmathlib.so")
except OSError as e:
print(f"无法加载动态链接库: {e}")
sys.exit(1)
# 调用整数加法函数
result_int = lib.calculate_sum(10, 25)
print(f"整数加法结果: {result_int}")
# 配置浮点数函数参数和返回类型
lib.compute_sum_float.argtypes = [ctypes.c_float, ctypes.c_float]
lib.compute_sum_float.restype = ctypes.c_float
result_float = lib.compute_sum_float(3.14, 2.86)
print(f"浮点数加法结果: {result_float}")
# 字符串拼接函数配置
lib.concat_strings.argtypes = [ctypes.c_char_p, ctypes.c_char_p]
lib.concat_strings.restype = ctypes.c_char_p
# 调用字符串拼接函数
result_str = lib.concat_strings(b"你好", b", 世界!")
print(f"字符串拼接结果: {result_str.decode('utf-8')}")
# 释放字符串内存
ctypes.c_void_p(lib.concat_strings.restype).in_dll(lib, "concat_strings")(result_str)
执行结果示例:
整数加法结果: 35
浮点数加法结果: 6.0
字符串拼接结果: 你好, 世界!
相关资源
- Python与Rust互操作技术详解
- PyO3项目官方文档
- Rust FFI手册