标签: wasm-bindgen

在使用wasm-bindgen时,如何解决无法使用生命周期导出函数的问题?

我正在尝试编写一个在浏览器中运行的简单游戏,并且考虑到浏览器,rust和wasm-bindgen所施加的限制组合,我很难对游戏循环进行建模.

浏览器中的典型游戏循环遵循以下一般模式:

function mainLoop() {
    update();
    draw();
    requestAnimationFrame(mainLoop);
}
Run Code Online (Sandbox Code Playgroud)

如果我要在rust/wasm-bindgen中建模这个确切的模式,它看起来像这样:

let main_loop = Closure::wrap(Box::new(move || {
    update();
    draw();
    window.request_animation_frame(main_loop.as_ref().unchecked_ref()); // Not legal
}) as Box<FnMut()>);
Run Code Online (Sandbox Code Playgroud)

与javascript不同,我无法main_loop从内部引用,因此这不起作用.

有人建议的另一种方法是遵循生命游戏例子中说明的模式.在高级别,它涉及导出包含游戏状态的类型,并包括可以在javascript游戏循环中调用的公共tick()render()函数.这对我不起作用,因为我的游戏状态需要生命周期参数,因为它实际上只包含规格 WorldDispatcher结构,后者具有生命周期参数.最终,这意味着我无法使用它导出它#[wasm_bindgen].

我很难找到解决这些限制的方法,并且正在寻找建议.

rust webassembly wasm-bindgen

4
推荐指数
1
解决办法
431
查看次数

使用 wasm-pack 构建时在 Rust 和 JavaScript 之间传递字符串

我正在构建一个 Chrome 扩展程序,并选择使用一些 WebAssembly 功能。我使用 wasm-pack 来构建源代码,因为它提供了--target web降低插入 Wasm 函数的复杂性的方法。在 Rust 和 JS 之间传递整数值可以无缝地工作,但我似乎无法将字符串传递给 Rust,反之亦然。

这是我正在处理的内容:

#[wasm_bindgen]
extern "C" {
    fn alert(s: &str);

    #[wasm_bindgen(js_namespace = console)]
    fn log(x: &str);
} 

#[wasm_bindgen]
pub extern "C" fn add_two(x: i32) -> i32 {
   x + 2
}

#[wasm_bindgen]
pub fn hello(name: &str) {
    log("Hello") // <-- passing a '&str' directly works. I can see it in the browser.
    log(name) // <-- does not seem to work. There is no output
    alert(&format!("Hello …
Run Code Online (Sandbox Code Playgroud)

rust rust-cargo webassembly wasm-bindgen wasm-pack

4
推荐指数
1
解决办法
1403
查看次数

我什么时候应该调用 wasm-pack 生成的 free() 方法?

我编写了一些 Rust 代码并使用 wasm-pack 对其进行了编译。free()我在生成的 .d.ts 文件中注意到这些方法:

export class PdfDoc {
  free(): void;
  ...
}
Run Code Online (Sandbox Code Playgroud)

PdfDoc拥有大量内存,高达 1GB,因此当 javascript 代码使用完这些内存时,正确释放所有内存以供重用非常重要。

问题:

  • 我什么时候应该调用这些free()方法?
  • 我需要显式调用它们还是会自动调用它们?
  • 如果我从不打电话给他们会怎样?

我搜索了“wasm-pack free method”,但这些搜索词组合没有找到任何有用的东西。

rust wasm-bindgen wasm-pack

4
推荐指数
1
解决办法
757
查看次数

Rust WebAssembly自定义元素内存释放错误

我的第一个Rust生产的WASM正在产生以下错误,我不知道如何进行调试。

wasm-000650c2-23:340 Uncaught RuntimeError: memory access out of bounds
    at dlmalloc::dlmalloc::Dlmalloc::free::h36961b6fbcc40c05 (wasm-function[23]:670)
    at __rdl_dealloc (wasm-function[367]:8)
    at __rust_dealloc (wasm-function[360]:7)
    at alloc::alloc::dealloc::h90df92e1f727e726 (wasm-function[146]:100)
    at <alloc::alloc::Global as core::alloc::Alloc>::dealloc::h7f22ab187c7f5835 (wasm-function[194]:84)
    at <alloc::raw_vec::RawVec<T, A>>::dealloc_buffer::hdce29184552be976 (wasm-function[82]:231)
    at <alloc::raw_vec::RawVec<T, A> as core::ops::drop::Drop>::drop::h3910dccc175e44e6 (wasm-function[269]:38)
    at core::ptr::real_drop_in_place::hd26be2408c00ce9d (wasm-function[267]:38)
    at core::ptr::real_drop_in_place::h6acb013dbd13c114 (wasm-function[241]:50)
    at core::ptr::real_drop_in_place::hb270ba635548ab74 (wasm-function[69]:192)
Run Code Online (Sandbox Code Playgroud)

上下文:从TypeScript自定义元素调用的最新Chrome,Rust wasm-bindgen代码,在影子DOM中的画布上运行。呈现到画布上的数据来自HTML5 AudioBuffer。所有rust变量都在本地范围内。

如果文档中仅出现一个实例,则Web组件可以正常工作,但是如果再出现其他实例,则如上所述将转储堆栈跟踪。该代码运行没有任何其他问题。

我知道Chrome中存在突出的内存错误-这是它们的外观吗,还是有经验的锈/毛病开发人员可以告诉我这是否异常?

js-sys = "0.3.19"
wasm-bindgen = "0.2.42"
wee_alloc = { version = "0.4.2", optional = true }
[dependencies.web-sys]
version = "0.3.4"
Run Code Online (Sandbox Code Playgroud)

rust代码很小,仅将AudioBuffer的两个通道呈现到提供的HTMLCanvasElement:

#[wasm_bindgen]
pub fn render(
    canvas: web_sys::HtmlCanvasElement,
    audio_buffer: &web_sys::AudioBuffer,
    stroke_style: …
Run Code Online (Sandbox Code Playgroud)

rust shadow-dom typescript wasm-bindgen

3
推荐指数
2
解决办法
143
查看次数

如何访问 Wasm (Rust) 中的 JS 对象属性?

我正在使用 wasm bindgen 并且有以下功能:

#[wasm_bindgen]
pub fn obj(o: &JsValue){
console::log_1(o);
}
Run Code Online (Sandbox Code Playgroud)

在 js 中我调用这个函数obj({name: "john"}); 并且它工作正常,但是当我尝试时它给出了指向的console::log_1(o.name); 错误unknown fieldname

rust webassembly wasm-bindgen

3
推荐指数
1
解决办法
2489
查看次数

如何从 wasm 返回一个元组到前端?

我是网络组装新手。我想使用 canvas 和 来创建一个简单的贪吃蛇游戏wasm_bindgen

我的生锈代码:

#[wasm_bindgen]
impl CanvasData {
    pub fn index_to_coordinate(&self, index: usize) -> (usize, usize) {
      (index % self.cell_count, index / self.cell_count)
    }
}
Run Code Online (Sandbox Code Playgroud)

CanvasData是一个保存画布数据的结构体,cell_count属性为usizetype,代表方形画布上水平和垂直格子的数量。这里我把画布上所有的网格从左到右、从上到下看成一个一维数组。该方法的目的是将数组索引映射到x、y坐标。我想返回一个元组并在前端调用它,如下所示:

const [x, y] = canvasData.index_to_coordinate(100)
Run Code Online (Sandbox Code Playgroud)

然而,在构建过程中出现了错误。

构建脚本:

wasm-pack build -t web
Run Code Online (Sandbox Code Playgroud)

错误:

error[E0277]: the trait bound `(usize, usize): IntoWasmAbi` is not satisfied
[0]   --> src\lib.rs:16:1
[0]    |
[0] 16 | #[wasm_bindgen]
[0]    | ^^^^^^^^^^^^^^^ the trait `IntoWasmAbi` is not implemented for `(usize, usize)`
[0]    |
[0] …
Run Code Online (Sandbox Code Playgroud)

frontend rust webassembly wasm-bindgen wasm-pack

3
推荐指数
1
解决办法
768
查看次数

如何将嵌套Vecs与wasm-bindgen一起使用?

嵌套的Vecs 似乎不适用于wasm-bindgen.那是对的吗?

我的目标是在Rust中使用生命游戏网格,我可以将其作为行返回,而不是Vec需要JavaScript处理索引的1D .我想到的两个解决方法是:

  1. 在Rust中实现一种自定义"迭代器",这是一种逐行返回行的方法.
  2. 将一维数组交给JavaScript但在JavaScript中编写一个包装器来处理索引并向消费者公开某种迭代器.

我不愿意使用其中任何一个,因为我希望这个库可以被JavaScript和本机Rust使用,而且我认为这两者在纯Rust的土地上都不会非常惯用.还有其他建议吗?

rust webassembly wasm-bindgen

2
推荐指数
1
解决办法
254
查看次数

如何使用 Rust 和 web-sys 将 Clamped&lt;Vec&lt;u8&gt;&gt; 转换为 Clamped&lt;&amp;mut [u8]&gt; ?

我正在使用 Rust 和 WebAssembly 操作像素数据,并且正在努力使用操作的像素创建新的 ImageData。

当我获取我的ImageData数据时,它返回一个Clamped<Vec<u8>>

   fn get_buffer_image_data(&self) -> Clamped<Vec<u8>> {
    let image_data = match self.buffer_ctx.get_image_data(0.0, 0.0, 640.0, 480.0) {
        Ok(d) => d,
        Err(_err) => panic!("failed to fetch buffer image data")
    };
    
    image_data.data()
}
Run Code Online (Sandbox Code Playgroud)

我在另一个函数中操作像素数据,然后尝试使用这些操作的像素创建新的 ImageData。问题是我只能用Clamped<&mut [u8]>创建新的 ImageData

    fn create_image_data(&self, data: Clamped<Vec<u8>>) {
        let imageData = ImageData::new_with_u8_clamped_array_and_sh(data, 640, 480);
    }

Run Code Online (Sandbox Code Playgroud)

但是,我收到的错误是:

mismatched types

expected `&mut [u8]`, found struct `std::vec::Vec`

note: expected struct `wasm_bindgen::Clamped<&mut [u8]>`
         found struct `wasm_bindgen::Clamped<std::vec::Vec<u8>>`
Run Code Online (Sandbox Code Playgroud)

我想我需要将一种类型转换为另一种类型。如何高效转换?我已经尝试这个有一段时间了,但我被困住了。我唯一的解决方案是将整个 Uint8ClampedArray 从我的 JS 发送到 wasm 。这是您可以使用的代码示例。请注意,如果您克隆此存储库,请查看分支problem …

rust webassembly wasm-bindgen

2
推荐指数
1
解决办法
726
查看次数

如何在 WebAssembly 中使用 web-sys 发出带有 JSON 正文的 POST 请求?

如何在 WebAssembly 中使用 web-sys 创建带有 JSON 主体的 POST 请求?

下面这个例子展示了如何发出 GET 请求,我需要更改opts.method("GET"); opts.method("POST"); 但我如何将 JSON 主体传递给 reqeuest.

    let mut opts = RequestInit::new();
    opts.method("GET");
    opts.credentials(web_sys::RequestCredentials::Include);
    
    let request = Request::new_with_str_and_init(
        "http://localhost:8080/api/v1/books",
         &opts
    ).unwrap();
    
    match web_sys::window() {
        Some(window) => {
            let _res = JsFuture::from(window.fetch_with_request(&request))
                .await
                .map(|err| web_sys::console::log_1(&format!("{:?}", err)
                .into()));
        },
        None => web_sys::console::log_1(&format!("window is none").into()),
    }
Run Code Online (Sandbox Code Playgroud)

rust webassembly wasm-bindgen yew web-sys

2
推荐指数
1
解决办法
2191
查看次数

如何通过WebAssembly将Rust闭包返回给JavaScript?

关于closure.rs的注释非常好,但是我不能让它从WebAssembly库中返回一个闭包.

我有这样的功能:

#[wasm_bindgen]
pub fn start_game(
    start_time: f64,
    screen_width: f32,
    screen_height: f32,
    on_render: &js_sys::Function,
    on_collision: &js_sys::Function,
) -> ClosureTypeHere {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

在该函数内部,我做了一个闭包,假设Closure::wrap是一个拼图,并从closure.rs复制):

let cb = Closure::wrap(Box::new(move |time| time * 4.2) as Box<FnMut(f64) -> f64>);
Run Code Online (Sandbox Code Playgroud)

如何从此回调start_game和应该返回什么ClosureTypeHere

我们的想法是start_game创建本地可变对象 - 比如相机,并且JavaScript方应该能够调用Rust返回的函数来更新该相机.

rust webassembly wasm-bindgen

1
推荐指数
1
解决办法
462
查看次数