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();
    }
}

示例解析

  1. ffi::Py_Initialize() - 初始化Python解释器
  2. ffi::PyUnicode_FromString() - 创建Python字符串对象
  3. ffi::PyDict_New() - 创建Python字典对象(用于globals和locals)
  4. ffi::PyRun_String() - 执行Python代码
  5. ffi::Py_DecRef() - 减少Python对象的引用计数
  6. ffi::PyErr_Print() - 打印Python错误
  7. 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
回到顶部