Rust与Python的无缝交互库python3-sys的使用,实现Rust高性能调用Python3 C API和原生扩展
Rust与Python的无缝交互库python3-sys的使用,实现Rust高性能调用Python3 C API和原生扩展
python3-sys
是 Rust 的 FFI 绑定库,用于调用 Python 3 的 C API。它支持 Python 3.3 或更高版本的 PEP 384 稳定 ABI。
使用方式
在 Cargo.toml
中添加依赖:
[dependencies.python3-sys]
version = "*"
完整示例
以下是使用 python3-sys
调用 Python C API 的完整示例:
use python3_sys as ffi;
use std::ffi::CString;
use std::ptr;
fn main() {
unsafe {
// 初始化Python解释器
ffi::Py_Initialize();
// 创建Python字符串对象
let py_code = CString::new("print('Hello from Python!')").unwrap();
let py_str = ffi::PyUnicode_FromString(py_code.as_ptr());
// 编译Python代码
let globals = ffi::PyDict_New();
let locals = ffi::PyDict_New();
let compiled = ffi::PyRun_String(py_code.as_ptr(), ffi::Py_file_input, globals, locals);
// 检查执行结果
if !compiled.is_null() {
ffi::Py_DecRef(compiled);
} else {
ffi::PyErr_Print();
}
// 清理资源
ffi::Py_DecRef(py_str);
ffi::Py_DecRef(globals);
ffi::Py_DecRef(locals);
// 关闭Python解释器
ffi::Py_Finalize();
}
}
示例解析
ffi::Py_Initialize()
- 初始化Python解释器ffi::PyUnicode_FromString()
- 创建Python字符串对象ffi::PyDict_New()
- 创建Python字典对象(用于globals和locals)ffi::PyRun_String()
- 执行Python代码ffi::Py_DecRef()
- 减少Python对象的引用计数ffi::PyErr_Print()
- 打印Python错误ffi::Py_Finalize()
- 关闭Python解释器
注意:所有Python C API调用都需要在unsafe
块中进行,因为它们直接操作内存和指针。
对于更高级的安全API,可以考虑使用rust-cpython库。
1 回复
Rust与Python的无缝交互库python3-sys使用指南
简介
python3-sys是一个Rust库,提供了对Python 3 C API的直接绑定,允许Rust代码与Python进行高性能交互。它特别适合需要将高性能Rust代码集成到Python项目中的场景,或者需要从Rust调用Python功能的场景。
主要特性
- 提供Python 3 C API的完整绑定
- 支持跨平台使用
- 自动处理Python解释器的初始化和清理
- 提供类型安全的Rust接口
使用方法
1. 添加依赖
首先在Cargo.toml中添加依赖:
[dependencies]
python3-sys = "0.4"
2. 基本使用示例
use python3_sys as ffi;
use std::ffi::CString;
fn main() {
unsafe {
// 初始化Python解释器
ffi::Py_Initialize();
// 执行简单的Python代码
let code = CString::new("print('Hello from Python!')").unwrap();
ffi::PyRun_SimpleString(code.as_ptr());
// 清理Python解释器
ffi::Py_Finalize();
}
}
3. 调用Python函数
use python3_sys as ffi;
use std::ffi::{CString, CStr};
use std::os::raw::c_char;
unsafe fn call_python_function() {
ffi::Py_Initialize();
// 导入math模块
let math_name = CString::new("math").unwrap();
let math_module = ffi::PyImport_ImportModule(math_name.as_ptr());
// 获取sqrt函数
let sqrt_name = CString::new("sqrt").unwrap();
let sqrt_func = ffi::PyObject_GetAttrString(math_module, sqrt_name.as_ptr());
// 准备参数
let args = ffi::PyTuple_New(1);
let value = ffi::PyFloat_FromDouble(16.0);
ffi::PyTuple_SetItem(args, 0, value);
// 调用函数
let result = ffi::PyObject_CallObject(sqrt_func, args);
// 获取结果
let result_str = ffi::PyUnicode_AsUTF8(ffi::PyObject_Str(result));
let c_str = CStr::from_ptr(result_str);
println!("Result: {}", c_str.to_str().unwrap());
// 清理
ffi::Py_DECREF(math_module);
ffi::Py_DECREF(sqrt_func);
ffi::Py_DECREF(args);
ffi::Py_DECREF(result);
ffi::Py_Finalize();
}
4. 创建Python扩展模块
use python3_s