Возвращение Rust Vec <Vec <i32 >> в JavaScript через WebAssembly - PullRequest
0 голосов
/ 16 сентября 2018

Я работаю над проектом с использованием Rust и WebAssembly, использующим цель «wasm32-unknown-unknown». Нет проблем вернуть Vec<i32> из моего кода Rust с помощью этой функции:

#[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
}

Это возвращает смещение, и я вызываю другую функцию из 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;
}

Используя это, я хочу создать функцию Rust, которая возвращает Vec<Vec<i32>>, однако она просто не будет работать:

#[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(), находится первая запись внешнего вектора, содержащая адрес как i32 первого элемента внутренний вектор (фактическое число). Однако по этому адресу, похоже, чепуха. Что я здесь не так делаю?

1 Ответ

0 голосов
/ 18 сентября 2018

Поскольку векторы в моем векторе имеют одинаковую длину, я могу использовать ящик lazy_static для инициализации статического Vec, заключенного в Mutex (чтобы иметь возможность изменить его позже). LEN_VEC - это длина вектора, а SIZE_INNER_VEC - размер одного вектора в моем статическом векторе.

Затем я добавляю i32 к статическому вектору и возвращаю адрес Vec, используя ARRAY.lock().unwrap().as_mut_ptr() as usize. С 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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...