如何在用 Rust 编写的 WebAssembly 模块中保持内部状态? [英] How do I keep internal state in a WebAssembly module written in Rust?

查看:54
本文介绍了如何在用 Rust 编写的 WebAssembly 模块中保持内部状态?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想对网络应用程序的每一帧的大量数据进行计算.JavaScript 只会使用其中的一个子集,因此与其在 WebAssembly 和 JavaScript 之间来回发送每一帧的整个数据集,不如在我的 WebAssembly 模块内部维护数据.

I want to do computations on a large set of data each frame of my web app. Only a subset of this will be used by JavaScript, so instead of sending the entire set of data back and forth between WebAssembly and JavaScript each frame, it would be nice if the data was maintained internally in my WebAssembly module.

在 C 中,类似这样的工作:

In C, something like this works:

#include <emscripten/emscripten.h>

int state = 0;

void EMSCRIPTEN_KEEPALIVE inc() {
    state++;
}

int EMSCRIPTEN_KEEPALIVE get() {
    return state;
}

在 Rust 中可以实现同样的事情吗?我试着用这样的 static 来做:

Is the same thing possible in Rust? I tried doing it with a static like this:

static mut state: i32 = 0;

pub fn main() {}

#[no_mangle]
pub fn add() {
    state += 1;
}

#[no_mangle]
pub fn get() -> i32 {
    state
}

但似乎static变量不能是可变的.

But it seems static variables cannot be mutable.

推荐答案

Francis Gagné 是绝对正确的全局变量一般让你的代码变得更糟,你应该避免它们.

Francis Gagné is absolutely correct that global variables generally make your code worse and you should avoid them.

然而,对于今天的WebAssembly的特定案例,我们不必担心这个问题:

However, for the specific case of WebAssembly as it is today, we don't have to worry about this concern:

如果你有多个线程

因此,如果我们有充分的理由,我们可以选择使用可变静态变量:

We can thus choose to use mutable static variables, if we have a very good reason to do so:

// Only valid because we are using this in a WebAssembly
// context without threads.
static mut STATE: i32 = 0;

#[no_mangle]
pub extern fn add() {
    unsafe { STATE += 1 };
}

#[no_mangle]
pub extern fn get() -> i32 {
    unsafe { STATE }
}

我们可以看到这个 NodeJS 驱动程序的行为:

We can see the behavior with this NodeJS driver program:

const fs = require('fs-extra');

fs.readFile(__dirname + '/target/wasm32-unknown-unknown/release/state.wasm')
  .then(bytes => WebAssembly.instantiate(bytes))
  .then(({ module, instance }) => {
    const { get, add } = instance.exports;
    console.log(get());
    add();
    add();
    console.log(get());
});

0
2

这篇关于如何在用 Rust 编写的 WebAssembly 模块中保持内部状态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆