我希望在Rust中重新编写Python项目的一些部分,以加快速度。其思想是使用Rust的FFI接口通过ctypes
连接到Python。我每晚用锈1.10。在
我需要将相当复杂的数组/结构返回给Python。但这不能正常工作。不幸的是,我在网上找不到任何关于这类问题的教程。在
extern crate libc;
use libc::{c_int, c_char, size_t, c_float, c_double};
use std::ffi::{CStr, CString};
use std::str;
use std::vec::Vec;
use std::slice;
use std::mem;
#[repr(C)]
pub struct CPeak {
// chemsc: *mut c_char, // adduct: c_char_p,
mz_exp: c_float,
mz_diff: c_float,
intensity: c_float,
resolution: c_float,
noise: c_float,
nb_frg: c_int,
frgs: *mut CFrg,
}
#[repr(C)]
pub struct CFrg {
mz_exp: c_float,
mz_diff: c_float,
intensity: c_float,
resolution: c_float,
noise: c_float,
}
#[no_mangle]
pub extern "C" fn standard_finder_get_standards(mut data: *mut *mut CPeak, mut len: *mut size_t) {
// fill 'peaks' vector
let peaks = find_standards(&standards.standards, "test.xml", 5.0, 10.0);
// Copy contents of peaks (Rust structure) to CPeaks (C structure).
// NOTE that CPeaks has a entry in the struct which is also a vector of
// structs (frgs)
let mut cpeaks: Vec<CPeak> = vec![];
for peak in &peaks {
// mk a vector frgs
let mut frgs: Vec<CFrg> = vec![];
if peak.frgs.len() > 0 {
for frg in &peak.frgs {
let f = CFrg {
mz_exp: frg.mz as c_float,
mz_diff: frg.mz_diff as c_float,
intensity: frg.intensity as c_float,
resolution: frg.resolution as c_float,
noise: frg.resolution as c_float,
};
frgs.push(f);
}
}
frgs.shrink_to_fit();
// mk a vector cpeaks
cpeaks.push(CPeak {
mz_exp: peak.mz as c_float,
mz_diff: peak.mz_diff as c_float,
intensity: peak.intensity as c_float,
resolution: peak.resolution as c_float,
noise: peak.resolution as c_float,
nb_frg: peak.frgs.len() as c_int,
frgs: frgs.as_ptr() as *mut CFrg, // <- add the frgs vector as c pointer (array)
});
}
cpeaks.shrink_to_fit();
unsafe {
*data = cpeaks.as_ptr() as *mut CPeak;
*len = cpeaks.len() as size_t;
}
mem::forget(cpeaks);
}
(Playground)。在
这段代码接受一个Rust向量(peaks: Vec<Peak>
),并将其内容复制到对应的C结构数组(cpeaks: Vec<CPeak>
)。在CPeak
内是指向CFrg
数组的另一个指针。cpeaks
向量作为引用调用返回,以便为错误返回值留出空间。在
当我试图用Python读取数据时,我有两个问题:
cpeaks
的第一个条目为空或垃圾CFrg
项都是垃圾。在我想问题在于cpeaks
的生命周期,它的生命周期可能不够长,无法在Python中访问。但是,我不知道怎么让它活下来。我尝试了Box
,但这没用。在
可以将rust代码称为python模块。在
https://developers.redhat.com/blog/2017/11/16/speed-python-using-rust/
我不确定这是否是你想要的,但也许值得一看。在
相关问题 更多 >
编程相关推荐