通过 WebAssembly 将 Rust Vec<Vec<i32>> 返回到 JavaScript
Returning a Rust Vec<Vec<i32>> to JavaScript via WebAssembly
我正在使用 "wasm32-unknown-unknown" 目标开发一个涉及 Rust 和 WebAssembly 的项目。使用此函数从我的 Rust 代码 return a Vec<i32>
没问题:
#[no_mangle]
pub extern "C" fn calc_vector() -> usize {
unsafe {
vec_len = 0;
}
let mut data: Vec<i32> = Vec::new();
for i in 0..1000 {
data.push(i);
}
unsafe {
vec_len = data.len();
}
data.as_mut_ptr() as usize
}
这个 return 是一个偏移量,我从 JS 调用另一个函数来获取我的 Vec
的长度。然后我再次在 JavaScript 中构建向量(知道 i32
-> 4x uint8
):
let vec_addr = exports.calc_vector();
let vec_len = exports.get_vec_len();
while(arr.length < vec_len) {
let numberUint8 = new DataView(view.buffer, vec_addr, 4);
let number = numberUint8.getInt32(0, true);
arr.push(number)
// move to next value in vector
vec_addr += 4;
}
使用这个,我想创建一个 return 是 Vec<Vec<i32>>
的 Rust 函数,但是,它不起作用:
#[no_mangle]
pub extern "C" fn calc_vector_in_vector() -> usize {
unsafe {
vec_len = 0;
elements_in_vect = 0;
}
let mut outer_vec: Vec<*mut i32> = Vec::new();
let mut inner_vec: Vec<i32> = Vec::new();
for i in 0..100 {
inner_vec.push(i);
unsafe {
elements_in_vect += 1;
}
}
outer_vec.push(inner_vec.as_mut_ptr());
unsafe {
vec_len = outer_vec.len();
}
outer_vec.as_mut_ptr() as usize
}
我认为我可以使用与单个 Vec
相同的逻辑:在从 calc_vector_in_vector()
编辑的地址 return 处是外部向量的第一个条目,包含地址为内部向量第一个元素的 i32
(实际数字)。但是,在这个地址上似乎是胡说八道。我在这里做错了什么?
因为我的向量中的向量都是相同长度的,所以我可以使用 lazy_static 板条箱来初始化一个静态的 Vec
包裹在 Mutex
中(以便能够改变稍后)。 LEN_VEC
是向量的长度,SIZE_INNER_VEC
是我的静态向量中一个向量的大小。
然后我将 i32
添加到静态向量,并使用 ARRAY.lock().unwrap().as_mut_ptr() as usize
添加 return Vec
的地址。使用 SIZE_INNER_VEC
和 LEN_VEC
,我可以在 JavaScript.
中重新创建向量中的向量
static mut LEN_VEC: usize = 0;
static mut SIZE_INNER_VEC: usize = 0;
lazy_static! {
// Wrap in Mutex to change later on
static ref ARRAY: Mutex<Vec<i32>> = Mutex::new(vec![]);
}
pub fn vector_in_vector() -> usize {
//set LEN_VEC
//set SIZE_INNER_VEC
ARRAY.lock().unwrap().as_mut_ptr() as usize
}
我正在使用 "wasm32-unknown-unknown" 目标开发一个涉及 Rust 和 WebAssembly 的项目。使用此函数从我的 Rust 代码 return a Vec<i32>
没问题:
#[no_mangle]
pub extern "C" fn calc_vector() -> usize {
unsafe {
vec_len = 0;
}
let mut data: Vec<i32> = Vec::new();
for i in 0..1000 {
data.push(i);
}
unsafe {
vec_len = data.len();
}
data.as_mut_ptr() as usize
}
这个 return 是一个偏移量,我从 JS 调用另一个函数来获取我的 Vec
的长度。然后我再次在 JavaScript 中构建向量(知道 i32
-> 4x uint8
):
let vec_addr = exports.calc_vector();
let vec_len = exports.get_vec_len();
while(arr.length < vec_len) {
let numberUint8 = new DataView(view.buffer, vec_addr, 4);
let number = numberUint8.getInt32(0, true);
arr.push(number)
// move to next value in vector
vec_addr += 4;
}
使用这个,我想创建一个 return 是 Vec<Vec<i32>>
的 Rust 函数,但是,它不起作用:
#[no_mangle]
pub extern "C" fn calc_vector_in_vector() -> usize {
unsafe {
vec_len = 0;
elements_in_vect = 0;
}
let mut outer_vec: Vec<*mut i32> = Vec::new();
let mut inner_vec: Vec<i32> = Vec::new();
for i in 0..100 {
inner_vec.push(i);
unsafe {
elements_in_vect += 1;
}
}
outer_vec.push(inner_vec.as_mut_ptr());
unsafe {
vec_len = outer_vec.len();
}
outer_vec.as_mut_ptr() as usize
}
我认为我可以使用与单个 Vec
相同的逻辑:在从 calc_vector_in_vector()
编辑的地址 return 处是外部向量的第一个条目,包含地址为内部向量第一个元素的 i32
(实际数字)。但是,在这个地址上似乎是胡说八道。我在这里做错了什么?
因为我的向量中的向量都是相同长度的,所以我可以使用 lazy_static 板条箱来初始化一个静态的 Vec
包裹在 Mutex
中(以便能够改变稍后)。 LEN_VEC
是向量的长度,SIZE_INNER_VEC
是我的静态向量中一个向量的大小。
然后我将 i32
添加到静态向量,并使用 ARRAY.lock().unwrap().as_mut_ptr() as usize
添加 return Vec
的地址。使用 SIZE_INNER_VEC
和 LEN_VEC
,我可以在 JavaScript.
static mut LEN_VEC: usize = 0;
static mut SIZE_INNER_VEC: usize = 0;
lazy_static! {
// Wrap in Mutex to change later on
static ref ARRAY: Mutex<Vec<i32>> = Mutex::new(vec![]);
}
pub fn vector_in_vector() -> usize {
//set LEN_VEC
//set SIZE_INNER_VEC
ARRAY.lock().unwrap().as_mut_ptr() as usize
}