实例--python和rust通过dll交互--python调用rust生成的dll

夹谷烨赫
2023-12-01

完整实例,已编译运行成功


cargo new rust-example --lib

Cargo.toml

[package]
name = "rust-example"
version = "0.1.0"
edition = "2021"

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

[dependencies]
peroxide = "0.31.6"
hex = "0.4.2"
serde = { version = "1.0.133", features = ["derive"] }
serde_json = "1.0.75"


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

lib.rs

#![allow(non_snake_case)]
#![allow(unused)]
extern crate peroxide;
use peroxide::fuga::*;
use std::str::from_utf8;
use serde::Serialize;
use serde::Deserialize;

use std::os::raw::c_char;
use std::ffi::{CStr, CString};

#[derive(Serialize, Deserialize,Debug)]
struct InputData {
    hh: Vec<f64>,
    EE: Vec<f64>
}

#[derive(Serialize, Deserialize,Debug)]
struct OutputData {
    h_E: Vec<f64>
}

#[no_mangle]
pub extern "C" fn cal_equivaluent_thickness_modulus(input: *const c_char) -> *const c_char {

    let name = unsafe {::std::ffi::CStr::from_ptr(input)};
    let name = name.to_str().unwrap();

    let input1 = hex::decode(name).unwrap();
    let input2 = from_utf8(&input1).unwrap(); 
    let input3:InputData = serde_json::from_str(input2).unwrap();
    
    let hh = input3.hh;
    let EE = input3.EE;

    let mut h1 = hh[0];
    let mut h2 = hh[1];
    let mut E1 = EE[0];
    let mut E2 = EE[1];

    let mut _h:Vec<f64> = Vec::new();
    let mut _E:Vec<f64> = Vec::new();

    for i in 2..=(hh.len()) {
        let h = h1 + h2;
        println!("rust {:?}", h);
        let E = (E1*h1.pow(3.0)+E2*h2.pow(3.0))/(h1+h2).pow(3.0) + 3.0/(h1+h2)*(1.0/(E1*h1)+1.0/(E2*h2)).pow(-1.0);
        
        _h.push(h);
        _E.push(E);
        
        if i==hh.len() {
            break;
        }
        h1 = h;
        h2 = hh[i];
        E1 = E;
        E2 = EE[i];

    }

    let mut h_E = vec![0.,0.];
    h_E[0] = _h[_h.len()-1];
    h_E[1] = _E[_E.len()-1];

    let out1 = OutputData {
        h_E:h_E
    };


    let h_EE = hex::encode((serde_json::to_string(&out1).unwrap()).into_bytes());

    let c_str_ping = CString::new(h_EE).unwrap().into_raw();

    c_str_ping

}



cd rust-example
cargo build --release

example.py

import json
from numpy import *
from ctypes import cdll,c_char_p

lib = cdll.LoadLibrary(r"target\release\cal_equivaluent_thickness_modulus.dll")

hh = [0.01,0.02,0.03,0.04,0.05,0.06,0.07]
EE = [100.,200.,300.,400.,500.,600.,700.,800.]

input_python = {
            'hh':hh, 
            'EE':EE
            }

lib.cal_equivaluent_thickness_modulus.restype = c_char_p  ####!!!!

result1 = json.loads(
      bytes.fromhex(
            lib.cal_equivaluent_thickness_modulus(
                  json.dumps(input_python,indent=4).encode().hex().encode() # dict -> json_str -> bytes -> hex_str -> bytes
                  ).decode() # bytes -> hex_str
            ).decode() # hex_str -> bytes -> json_str
      )  # json_str -> dict

print(result1,type(result1))
print(result1["h_E"],type(result1["h_E"]))
print(result1["h_E"][0])


 类似资料: