在python 代码中调用rust 源码库操作步骤

原理:

将rust源码编译为一个python lib库 ,在python中调用这个lib库。

步骤:

使用 PyO3 创建 Python 扩展模块

PyO3 是一个非常流行的库,允许你将 Rust 代码编译为 Python 扩展模块,并在 Python 中直接调用它。

安装maturin
python 复制代码
pip install maturin

创建 Rust 项目

  • 在rust 项目中创建lib.rs文件

在rust 中,lib.rs 默认编译为库,而main.rs默认编译为可执行文件

  • 编辑lib.rs文件
rust 复制代码
use pyo3::prelude::*;
use pyo3::wrap_pyfunction;

#[pyfunction]
fn add_measurement_signal(
    a2l_info: &mut A2lFileInfo,
    measurement_info: &MeasurementInfo,
) -> PyResult<()> {
    a2l_info.add_measurements.push(measurement_info.clone());
    Ok(())
}

#[pyfunction]
fn deleted_measurements_signal(
    a2l_info: &mut A2lFileInfo,
    measurement_info: &MeasurementInfo,
) -> PyResult<()> {
    a2l_info.delete_measurements.push(measurement_info.clone());
    Ok(())
}

#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MeasurementData {
    #[pyo3(get, set)]
    pub name: String,
    #[pyo3(get, set)]
    pub data_type: String,
    #[pyo3(get, set)]
    pub address: u64,
    #[pyo3(get, set)]
    pub byte_size: u32,
}

#[pymethods]
impl MeasurementData {
    #[new]
    fn new(name: String, data_type: String, address: u64, byte_size: u32) -> Self {
        MeasurementData {
            name,
            data_type,
            address,
            byte_size,
        }
    }

    // 显式实现 copy 方法来进行深拷贝
    fn copy(&self) -> MeasurementData {
        self.clone() // 调用 Clone trait 进行深拷贝
    }
}

#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MeasurementInfo {
    #[pyo3(get, set)]
    pub module_name: String,
    #[pyo3(get, set)]
    pub group_name: String,
    #[pyo3(get, set)]
    pub measurement_data: MeasurementData,
}

#[pymethods]
impl MeasurementInfo {
    #[new]
    fn new(module_name: String, group_name: String, measurement_data: MeasurementData) -> Self {
        MeasurementInfo {
            module_name,
            group_name,
            measurement_data,
        }
    }

    // 显式实现 copy 方法来进行深拷贝
    fn copy(&self) -> MeasurementInfo {
        self.clone() // 调用 Clone trait 进行深拷贝
    }
}

#[pyclass]
#[derive(Debug, Clone, PartialEq, Eq)]
struct A2lFileInfo {
    #[pyo3(get, set)]
    pub file_name: String,
    #[pyo3(get, set)]
    pub project_name: String,
    #[pyo3(get, set)]
    pub modules: Vec<String>,
    #[pyo3(get, set)]
    pub groups: Vec<String>,
    #[pyo3(get, set)]
    pub delete_measurements: Vec<MeasurementInfo>,
    #[pyo3(get, set)]
    pub add_measurements: Vec<MeasurementInfo>,
}

#[pymethods]
impl A2lFileInfo {
    #[new]
    fn new(
        file_name: String,
        project_name: String,
        modules: Vec<String>,
        groups: Vec<String>,
        read_measurements: Vec<MeasurementInfo>,
        delete_measurements: Vec<MeasurementInfo>,
        add_measurements: Vec<MeasurementInfo>,
    ) -> Self {
        A2lFileInfo {
            file_name,
            project_name,
            modules,
            groups,
            read_measurements,
            delete_measurements,
            add_measurements,
        }
    }

    // 显式实现 copy 方法来进行深拷贝
    fn copy(&self) -> A2lFileInfo {
        self.clone() // 调用 Clone trait 进行深拷贝
    }
}

#[pymodule]
fn a2l_edit_lib(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_function(wrap_pyfunction!(add_measurement_signal, m)?)?;
    m.add_function(wrap_pyfunction!(deleted_measurements_signal, m)?)?;
    m.add_class::<A2lFileInfo>()?;
    m.add_class::<MeasurementInfo>()?;
    m.add_class::<MeasurementData>()?;
    Ok(())
}

对于内部结构体,需要将成员变量设置pub 并添加修饰符:

rust 复制代码
#[pyo3(get, set)]
pub name: String,
  • 配置Cargo.toml
rust 复制代码
[package]
name = "xxxx_lib"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib"]  # 编译为动态链接库

# 在 [dependencies] 部分添加
[dependencies]

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

[workspace]

resolver = "2"

[patch.crates-io]
  • 编译rust lib
rust 复制代码
cargo check
maturin build 

在target/wheels 目录下生成lib 安装文件

  • 安装lib库
bash 复制代码
pip install --force-reinstall xxx_lib-0.1.0-cp310-cp310-manylinux_2_34_x86_64.whl

在python 源码中调用rust lib

python 复制代码
import xxx_lib

# 创建 MeasurementData 和 MeasurementInfo
data = a2l_edit_lib.MeasurementData(signal.name, signal.type_name, address, byte_size)
data_info = a2l_edit_lib.MeasurementInfo(module_name, group_name, data.copy())
a2l_edit_lib.add_measurement_signal(self.a2l_parser_info, data_info)
a2l_edit_lib.deleted_measurements_signal(self.a2l_parser_info, data_info)

可以直接使用对外导出的结构体对象,在测试中发现,可以读取A2lFileInfo 对象,但是没办法修改内部值,只能通过增加rust 接口函数来实现对A2lFileInfo 对象的修改。

相关推荐
熬夜敲代码的小N2 分钟前
仓颉ArrayList动态数组源码分析:从底层实现到性能优化
数据结构·python·算法·ai·性能优化
yumgpkpm3 分钟前
Hadoop大数据平台在中国AI时代的后续发展趋势研究CMP(类Cloudera CDP 7.3 404版华为鲲鹏Kunpeng)
大数据·hive·hadoop·python·zookeeper·oracle·cloudera
沉默媛29 分钟前
如何下载安装以及使用labelme,一个可以打标签的工具,实现数据集处理,详细教程
图像处理·人工智能·python·yolo·计算机视觉
唆了蜜.32 分钟前
ESLint: Expected indentation of * spaces but found *. (style/indent)
开发语言·javascript·vue·webstorm
生信小窝34 分钟前
基于R获取全球海岸线数据获取与导出
开发语言·r语言
HMS Core38 分钟前
【FAQ】HarmonyOS SDK 闭源开放能力 — Push Kit
linux·python·华为·harmonyos
程序员卷卷狗38 分钟前
联合索引的最左前缀原则与失效场景
java·开发语言·数据库·mysql
2739920291 小时前
qInstallMessageHandler(重定向至log文件)
开发语言·qt
yddddddy1 小时前
关于vue3
开发语言·vue
CODE_RabbitV1 小时前
【1min 速通 -- PyTorch 张量数据类型】张量类型的获取、转化与判别
人工智能·pytorch·python