使用wasm_bindgen公开香草Rust类

时间:2019-06-19 22:21:47

标签: rust webassembly wasm-bindgen

我正在学习如何通过this tutorial使用Rust将WASM定位为目标。我希望能够将域代码与将其公开给WASM的代码分开。这样,我可以毫无麻烦地在非WASM应用程序中重用域代码。我找不到执行此操作的任何示例,也不知道它是否受支持。

现在,我正在做的是将我的香草Rust结构包装到另一个具有围绕域类的公共方法进行包装的结构。我几乎可以确定这不是正确的方法,但目前可以使用。

我希望能够将CellValue绑定到WASM。

// Inside a vanilla Rust library

// We could bind CellValue with #[wasm_bindgen],
// but I want to keep all WASM stuff out of this library
enum CellValue {
    Live = 0,
    Dead = 1
}

// ...

struct World {
    // ...
    cells: Vec<CellValue> // need to bind a direct reference to the values in here
}

这就是将World暴露于WASM的方式-我将其包装在GOL中并在GOL中实现方法,以便WASM可以与World进行交互。

// Inside the wasm binding library

#[wasm_bindgen]
pub struct GOL {
    world: gol::World
}


#[wasm_bindgen]
impl GOL {
    pub fn make_new(rows: usize, cols: usize) -> Self
    {
        Self {
            world: GameOfLife::make_new(rows, cols)
        }
    }

    // and so on...
}

对于CellValue,我无法模仿GOL所采用的方法,因为我需要能够引用World所保存的每个单元格中的数据。

就像我说的那样,我之所以跳过这些障碍,是为了避免使用#[wasm_bindgen]添加域代码。甚至有可能获得这种绑定吗?

1 个答案:

答案 0 :(得分:0)

更新:通过查看this库,我找到了可行的解决方案。这是以这种方式编写的ZX Spectrum模拟器,其中wasm_bindgen被隔离在界面中。范例是通过不安全的指针进行互操作,如下所示:

#[wasm_bindgen]
pub fn get_cell_value(world: *mut World) -> *const CellValue // return a raw reference to the type defined in the domain
{
    // Return a reference to the first element in the array
}

然后,在JavaScript方面,执行以下操作:

import { memory } from "gol/gol_bg"; // Actual WASM generated by wasm_bindgen
import { make_world, get_cell_array } from "wasm-game-of-life";

// ...

const world = make_world(width, height);

const cellsPtr = get_cells_array(world); // Pointer to the first element of the Vec

const cells = new Uint8Array(memory.buffer, cellsPtr, width * height);