PyO3: Python 调用 Rust 代码
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,则会一直报错!
Rust 编程技术、程序设计 和 源码范例:Rust 语言是一种高效、可靠的系统级编程语言。它被设计为保证内存和线程安全,并能防止段错误。同时,作为系统级的编程语言,它的基本理念是 “零开销抽象”,运行速度与 C/C++ 同级。