PyO3: python调用rust代码尝试

79 篇文章 6 订阅

PyO3功能很强大,是python和rust之间交互桥梁。今天主要试验一下python端调用rust端编译的代码库。

说明:本文环境中在windos平台和WSL下 unbuntu18.04平台。linux其它平台或其它平台请参看github上pyo3的说明。
另外,python要求python3版本以上。

一、rust 端

在rust端创建pyrust库文件:

cargo new myrust --lib

同时在lib.rs文件中,写入以下代码:
在这里插入图片描述其中,#[pyfunction]是指写入rust方法,pyo3自动会转成python能调用的函数;
#[pymodule]是指把这些函数放在一个module下。

接下来:cargo.toml文件
在这里插入图片描述
其中,crate-type中的选项比较重要;还有依赖项pyo3的设置。

接下来build:

在这里插入图片描述可以在target/release下发现,相关的dll文件
在这里插入图片描述以上rust端工作基本完成。

记住这个文件:my_rust.dll,包括路径。后面有重要用途。切记!

二、python端

1、我们新建一个python文件的文件夹rust2py,写入一个test.py文件。

代码如下:
在这里插入图片描述
2、我们把此前提过的“my_rust.dll”,拷贝至rust2py下,与test.py同一级目录下。

需要注意的是,不要把"my_rust.pdb"文件拷过来,我开始就把"pdb"和"pyd"搞错了。

3、对dll文件进行重命名:

bash my_rust.dll => my_rust.pyd.

这样,python端的准备工作就ok了。

这样,你就可以运行test.py文件了!

在这里插入图片描述

三、相关代码

1、lib.rs文件


use pyo3::prelude::*;
use pyo3::wrap_pyfunction;

#[pyfunction]
fn add(x: f64, y: f64) -> f64 {
    return x+y
}

#[pyfunction]
fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
    Ok((a + b).to_string())
}

#[pymodule]
fn my_rust(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
    m.add_function(wrap_pyfunction!(add, m)?)?;
    m.add_function(wrap_pyfunction!(sum_as_string, m)?)?;
    Ok(())
}

2、cargo.toml

[package]
name = "myrust"
version = "0.1.0"
authors = ["songroom"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

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

[dependencies.pyo3]
version = "0.13.2"
features = ["extension-module"]

3、test.py

from my_rust import add,sum_as_string
print("add value :",add(1,2))
print("sum_as_string: ",sum_as_string(5,6))
print("hello world")

四、WSL 下unbuntu平台

前面是尝试windows平台。对于linux unbuntu版本下(我这儿是WSL2 下unbuntu18.04):

sudo apt install python3-dev python-dev

创建了一个rust2py项目:

在这里插入图片描述在这里插入图片描述
对应release下编译成的:librust2py.so文件
需要把这个文件copy到.py文件同一目录下,并改名:

librust2py.so文件 => rust2py.so文件

最后在WSL下,需要注意要用python3来执行。
在这里插入图片描述如果没有注意用python而不是python3,则会一直报错!

在这里插入图片描述

  • 5
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以通过使用`pyo3`库来将`Python`类方法导出到`Rust`,然后在`Rust`中调用这些方法。以下是一个例子: ```python # example.py class MyClass: def __init__(self, name): self.name = name def greet(self): print(f"Hello, {self.name}!") ``` ```rust // main.rs use pyo3::prelude::*; use pyo3::wrap_pyfunction; #[pyclass] struct MyClass { name: String, } #[pymethods] impl MyClass { #[new] fn new(name: String) -> Self { Self { name } } fn greet(&self) -> PyResult<()> { Python::with_gil(|py| { let gil = pyo3::Python::acquire_gil(); let py = gil.python(); let locals = [("self", pyo3::PyObject::from(self))].into_py_dict(py); py.run("self.greet()", None, Some(&locals))?; Ok(()) }) } } #[pyfunction] fn create_my_class(name: String) -> PyResult<MyClass> { Ok(MyClass::new(name)) } #[pymodule] fn example(_py: Python, m: &PyModule) -> PyResult<()> { m.add_class::<MyClass>()?; m.add_wrapped(wrap_pyfunction!(create_my_class))?; Ok(()) } fn main() -> PyResult<()> { Python::with_gil(|py| { let example_module = PyModule::new(py, "example")?; example_module.add_class::<MyClass>()?; example_module.add_wrapped(wrap_pyfunction!(create_my_class))?; let locals = [("example", example_module)].into_py_dict(py); py.run("import example", None, Some(&locals))?; let my_class = example_module .call("create_my_class", ("World",), None)? .extract::<MyClass>()?; my_class.greet()?; Ok(()) }) } ``` 这个例子中,我们使用`pyo3`库将`Python`类`MyClass`导出到`Rust`中。在`Rust`代码中,我们可以通过调用`MyClass`的`greet`方法来执行`Python`类中的`greet`方法。我们还编写了一个`Rust`函数`create_my_class`,用于创建`MyClass`实例并将其返回到`Python`。最后,我们在`Rust`中调用`Python`代码来创建`MyClass`实例,然后调用`greet`方法来打印出“Hello, World!”的消息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值