4.1 python中调用rust程序

概述

使用rust-cpython将rust程序做为python模块调用;

通常为了提高python的性能;

参考

https://github.com/dgrunwald/rust-cpython

创建rust lib库

cargo new rust2py --lib

或者使用IDE创建一个rust lib库项目

Cargo.toml

[package]
name = "rust2py"
version = "0.1.0"
edition = "2018"


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

[dependencies.cpython]
version = "0.3"
features = ["extension-module"]

lib.rs

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }
}

#[macro_use]
extern crate cpython;

use cpython::{PyResult, Python, py_module_initializer, py_fn};


pub fn print_str(a: String) -> String {
    print!("{:#?}",a);
    a
}

pub fn print_str_py(_: Python, a: String) -> PyResult<String>{
    let mm = print_str(a);
    Ok(mm)
}


// logic implemented as a normal rust function
fn sum_as_str(a:i64, b:i64) -> String {
    format!("{}", a + b).to_string()
}

// rust-cpython aware function. All of our python interface could be
// declared in a separate module.
// Note that the py_fn!() macro automatically converts the arguments from
// Python objects to Rust values; and the Rust return value back into a Python object.
fn sum_as_str_py(_: Python, a:i64, b:i64) -> PyResult<String> {
    let out = sum_as_str(a, b);
    Ok(out)
}

py_module_initializer!(rust2py, init_rust2py, PyInit_rust2py, |py, m| {
    m.add(py, "__doc__", "This module is implemented in Rust.")?;
    m.add(py, "print_str", py_fn!(py, print_str_py(a: String)))?;
    m.add(py, "sum_as_str", py_fn!(py, sum_as_str_py(a: i64, b:i64)))?;
    Ok(())
});

 注意:py_module_initializer方法的参数的中rust2py一定要与模块的名称一致,这个不是随便写的字符串名称,比如PyInit_rust2py就表示将来在python中调用的模块名称是rust2py

编译并复制到python的模块

cargo build 
cp target/debug/librust2py.so /opt/app/anaconda3/lib/python3.8/site-packages/rust2py.so

注意:复制到python模块的so没有lib前缀

其他安装参考

https://github.com/PyO3/setuptools-rust

python调用模块

ai@aisty:/opt/app/anaconda3/lib/python3.8/site-packages$ python3.8
Python 3.8.5 (default, Sep  4 2020, 07:30:14) 
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import rust2py
>>> rust2py.sum_as_str(2,5)
'7'
>>> rust2py.print_str("from rust")
'from rust'
>>> 

更多数据类型方法请参考

http://dgrunwald.github.io/rust-cpython/doc/cpython/

原文地址:https://www.cnblogs.com/perfei/p/15227965.html