想通过cdylib使用rust函数,返回Vec<Vec<[f64;2]>>
到python里,最外层固定是4个大小。因为Vec套着Vec套着Array,想着用struct,实现如下:
#[repr(C)]
pub struct DataBase {
a: Data,
b: Data,
c: Data,
d: Data,
}
impl DataBase {
fn new(mut data: Vec<Data>) -> Self {
let d = data.pop().unwrap();
let c = data.pop().unwrap();
let b = data.pop().unwrap();
let a = data.pop().unwrap();
Self {a, b, c, d}
}
}
#[repr(C)]
pub struct Data {
pair: *mut Pair,
pair_num: i32,
pair_capacity: i32,
}
impl Data {
fn new(mut pairs: Vec<Pair>) -> Self {
let pair = pairs.as_mut_ptr();
let pair_num = pairs.len() as i32;
let pair_capacity = pairs.capacity() as i32;
mem::forget(pairs);
Self { pair, pair_num, pair_capacity }
}
}
#[repr(C)]
pub struct Pair {
pair0: f64,
pair1: f64,
}
impl Pair {
fn new(pair0: f64, pair1: f64) -> Self {
Self { pair0, pair1 }
}
}
impl From<Vec<Vec<[f64; 2]>>> for DataBase {
fn from(raw_database: Vec<Vec<[f64; 2]>>) -> Self {
let mut database = vec![];
for data in raw_database.iter() {
let mut foo_pairs = vec![];
for pair in data.iter() {
foo_pairs.push(Pair::new(pair[0], pair[1]));
}
database.push(Data::new(foo_pairs));
}
Self::new(database)
}
}
#[no_mangle]
pub extern "C" fn generate_data(x: f64) -> *mut DataBase {
let ret: Vec<Vec<[f64; 2]>> = pre_lib::generate_data(x).unwrap();
let mut database = DataBase::from(ret);
println!("arr len 0 = {}, arr len 1= {}", database.a.pair_num, database.c.pair_num);
let ret: *mut DataBase = &mut database;
mem::forget(database);
ret
}
发现一个奇怪的问题,就是不用println!
这句,貌似DataBase
占据的内存就被释放了,数据就被清空了,但是我明明使用了mem::forget
。而当我调试的时候意外加入了这个println!
结果它就正常了。
另外求教下,这个*mut DataBase
传回来之后怎么销毁啊,直接进入fn free_database(_database: *mut DataBase) -> ()
可以就销毁了么?还是说需要重做*mut Pair
到Vec<Pair>
?
1
共 3 条评论, 1 页
评论区
写评论写错了,修订一下:
难怪感觉稍微有点内存泄露,这下正确的使用了
Box::from_raw
之后,没有任何泄露问题了。--
👇
Grobycn:
DataBase
是在栈上分配的,后面的程序会可能覆盖这一部分内存,相当于丢失了指向底层数据的指针。 看看下面的程序,可以看到底层的浮点数数据还在,但是DataBase
已经被回收了。 可以考虑用Box::leak
和Box::from_raw
playground
感谢大佬,成功了。类似这样:
释放的时候类似这样:
目前运行良好,也没有啥特别明显的内存泄露问题了。
感谢!
--
👇
Grobycn:
DataBase
是在栈上分配的,后面的程序会可能覆盖这一部分内存,相当于丢失了指向底层数据的指针。 看看下面的程序,可以看到底层的浮点数数据还在,但是DataBase
已经被回收了。 可以考虑用Box::leak
和Box::from_raw
playground
DataBase
是在栈上分配的,后面的程序会可能覆盖这一部分内存,相当于丢失了指向底层数据的指针。 看看下面的程序,可以看到底层的浮点数数据还在,但是DataBase
已经被回收了。 可以考虑用Box::leak
和Box::from_raw
playground