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,则会一直报错!