标签: wasm-bindgen

错误[E0463]:在为 wasm32-unknown-unknown 构建 Rust 项目时找不到“core”的包

我收到以下错误消息:

error[E0463]: can't find crate for `core`
  |
  = note: the `wasm32-unknown-unknown` target may not be installed

error: aborting due to previous error

For more information about this error, try `rustc --explain E0463`.
error: could not compile `cfg-if`

To learn more, run the command again with --verbose.
Run Code Online (Sandbox Code Playgroud)

当我运行这个命令时:

cargo build --target wasm32-unknown-unknown
Run Code Online (Sandbox Code Playgroud)

compilation rust rust-cargo webassembly wasm-bindgen

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

用 Rust 处理 WebAssembly 中的闭包而不是使用忘记和泄漏内存的更好方法是什么?

当使用Closures为 JavaScript 提供回调时,有什么更好的方法来避免释放它们?所述WASM-定义BindGen引导建议使用.forget,但承认其基本上泄漏内存。

通常我们会存储句柄以便稍后在适当的时候被删除,但现在我们希望它是一个全局处理程序,所以我们使用该forget方法来删除它而不会使闭包无效。请注意,这是 Rust 中的内存泄漏,因此应该谨慎地进行!

它暗示将闭包存储到适合丢弃的时间。在alexcrichton对上一个问题的回答中,他提到...

[...] 如果它 [...] 只被调用一次,那么你可以使用Rc/RefCell来删除Closure闭包本身的内部(使用一些内部可变性恶作剧)

但他没有提供这种方法的例子。

封闭的文档也给出了参考关闭返回JavaScript的背景下,以让它处理时释放参考的例子。

如果我们cb放在这里,它会在时间间隔过去时引发异常。相反,我们句柄返回给 JS,以便 JS 可以决定何时取消间隔并释放闭包。

我还想象有一些方法可以#[wasm_bindgen]在公共函数上使用生命周期或宏等功能来避免这个问题,但我无法弄清楚如何做到这一点。

我的问题是,使用.forget从 Rust 传递回 JavaScript 的闭包有哪些替代方法,我能否请您查看每个正在使用的选项的简单示例?

closures rust webassembly wasm-bindgen

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

如何使用 wasm-bindgen 将 Vec 作为类型化数组返回?

我有一个Vec我想返回并使用 wasm-bindgen 转换为类型化数组,即将 a 转换Vec<u32>Uint32Array. 根据我的研究,wasm-bindgen 现在无法自动处理这些转换(就像它所做的那样String),而您必须使用js-sys板条箱。然而,我还没有找到如何使用这个板条箱的明确示例。如果可以提供如何使用它的清晰简单的示例,我们将不胜感激。

为了完整起见,如果答案能够解释如何公开返回 a 的函数Vec<u32>以及结构成员,即如何将这些定义转换为可用的内容,那就太好了:

#[wasm_bindgen]
pub fn my_func() -> Vec<u32> {
    inner_func() // returns Vec<u32>
}

#[wasm_bindgen]
pub struct my_struct {
    #[wasm_bindgen(readonly)]
    pub my_vec: Vec<u32>,
}
Run Code Online (Sandbox Code Playgroud)

vector rust typed-arrays wasm-bindgen

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

Rust wasm-bindgen 结构与字符串

我正在尝试导出以下结构:

#[wasm_bindgen]
#[derive(Eq, PartialEq, Debug, Clone)]
pub enum TokenType {
    KeywordLiteral,
    NumberLiteral,
    Operator,
    Separator,
    StringLiteral,
}

#[wasm_bindgen]
#[derive(Eq, PartialEq, Debug, Clone)]
pub struct Token {
    pub typ: TokenType,
    pub val: String,
}
Run Code Online (Sandbox Code Playgroud)

但我得到:

error[E0277]: the trait bound `token::TokenType: std::marker::Copy` is not satisfied
  --> src\tokenizer\token.rs:17:14
   |
14 | #[wasm_bindgen]
   | --------------- required by this bound in `__wbg_get_token_typ::assert_copy`
...
17 |     pub typ: TokenType,
   |              ^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `token::TokenType`
Run Code Online (Sandbox Code Playgroud)

也:

error[E0277]: the trait bound `std::string::String: std::marker::Copy` is …
Run Code Online (Sandbox Code Playgroud)

rust wasm-bindgen

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

为什么将 DOM 对象作为“exnternref”传递比通过 JS 值表传递“慢”?

exnternref我制定了一个基准测试,通过将 DOM 对象作为s 传递给 Wasm 函数来衡量调用 DOM API 的速度。这是要测量的函数(用 Rust 编写并由 rustc 1.55.0 编译):

#[wasm_bindgen]
pub fn append_and_remove(elem: web_sys::Element) {
    let doc = web_sys::window().unwrap().document().unwrap();
    let child = &doc.create_element("br").unwrap();
    elem.append_with_node_1(child).unwrap();
    let _ = elem.remove_child(child).unwrap();
}
Run Code Online (Sandbox Code Playgroud)

(完整代码请参见https://github.com/igrep/wasm-reference-types-examples )

我比较了两个 Wasm 模块(及其 JS 包装器)和等效的 JavaScript 代码:一个(“带引用类型”版本)使用 进行预处理wasm-bindgen --reference-types,另一个(“无引用类型”版本)仅使用 进行预处理wasm-bindgen

这是运行一百万次的结果:

浏览器 标签 时间(毫秒)
火狐94.0.1 无参考类型 2167
带参考类型 2687
仅 JavaScript 第637章
铬95.0.4638.69 无参考类型 3432
带参考类型 4129
仅 JavaScript 1039
边缘95.0.1020.44 无参考类型 3416
带参考类型 3858
仅 JavaScript 第1187章 …

rust webassembly wasm-bindgen

8
推荐指数
0
解决办法
589
查看次数

WebAssembly 中的多线程

如果您回答我关于 WebAssembly 多线程的问题,我将不胜感激。我想用 2 个线程(主线程和辅助线程)实现代码,这样就有一个全局变量用作辅助线程中的计数器变量,并在循环中递增它。和主线程,读取计数器变量,一次在运行指令之前,一次在运行指令之后(测量完成该指令所需的时间)。我已经实现了这个代码:


#include "pthread.h"
#include <stdio.h>
#include <unistd.h>
#include<chrono>

int i;
int counter;

void* timerfunction( void *ptr)
{
  printf ("Thread Timer!\n");
  //cout<<"Thread Timer!"<<endl;
  while(1)
  {
    counter=counter+1;
  }
  pthread_exit("The thread was exited!");
}




int main()
{
    pthread_t thread_id;
    void *thread_result;
    int c=0;
    int l=pthread_create(&thread_id,NULL,timerfunction,&c);
    int t1= counter;//reading the counter for the first one

    //intended instruction that we want to measure its execution time   

    int t2= counter;//reading the counter for the second one
    int t3 = t2 - t1;//computing …
Run Code Online (Sandbox Code Playgroud)

multithreading emscripten webassembly wasm-bindgen

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

为什么 Rust WASM 指针和 JS 指针的值不同?

假设我在 Rust 代码中有以下定义:

#[wasm_bindgen]
pub struct RustType {
    foo: usize
}

#[wasm_bindgen]
impl RustType {
    #[wasm_bindgen(constructor)]
    pub fn new() -> Self {
        Self { foo: 100 }
    }
}

#[wasm_bindgen]
pub fn print_addr(obj: &RustType) {
    console_log!("rust addr = {}", obj as *const _ as u32);
}
Run Code Online (Sandbox Code Playgroud)

JS 代码创建一个实例RustType并将其传递给print_addr函数:

var obj = new RustType();
print_addr(obj);
Run Code Online (Sandbox Code Playgroud)

修改生成的print_addr函数后index_bg.js如下:

export function print_addr(obj) {
    _assertClass(obj, RustType);
    console.log("js addr = ", obj.ptr); // <== added this line
    if …
Run Code Online (Sandbox Code Playgroud)

javascript rust webassembly wasm-bindgen

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

如何使用 wasm-bindgen 和 --target no-modules 导入 JavaScript 函数?

我正在尝试弄清楚如何使用 Rust 和 wasm-bindgen 调用 JavaScript 函数。由于缺乏浏览器支持,我无法将 wasm-bindgen 与 ES6 模块与 Web Worker 一起使用。

据我所知,声明存在一个 JavaScript 函数供我在 Rust 端调用是很简单的

#[wasm_bindgen]
extern {
    fn logProgress(percent: f64);
}
Run Code Online (Sandbox Code Playgroud)

但是我不知道在哪里定义 JavaScript 实现。如果我尝试从 JavaScript 调用 Rust 函数来调用 undefined,logProgress那么我会收到运行时错误:Error: logProgress is not defined

我可以从 wasm-bindgen 文档中看到,如果我将 wasm-bindgen 与 ES6 模块一起使用,那么我可以将 rust 代码更改为

#[wasm_bindgen(module = "/progress.js")]
extern {
    fn logProgress(percent: f64);
}
Run Code Online (Sandbox Code Playgroud)

并在中声明 JavaScript 函数progress.js

export function logProgress(percent) {
    console.log(percent)
    // actual implementation would not just log
}
Run Code Online (Sandbox Code Playgroud)

由于我是通过全局导入 Rust …

javascript rust webassembly wasm-bindgen

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

使用 Yew 回调作为 wasm_bindgen 闭包

这个问题是为 Yew v0.19 编写的

异步外部 JavaScript 函数可以通过Closures在 Rust 中使用,作为传入的函数:


#[wasm_bindgen]
extern "C" {
    fn setInterval(closure: &Closure<dyn FnMut()>, time: u32) -> i32;
}

// ...

let cb = Closure::new(|| {
    log("interval elapsed!");
});

let interval_id = setInterval(&cb, 1_000);
Run Code Online (Sandbox Code Playgroud)

这对于迂腐的例子来说很好,但是Closure有一个关键的要求 - 所应用的函数需要有一个'static生命周期。同样,对于 Yew 应用程序,自发响应的完美机制是枚举Message,并将其update()命名为Model. 然而,(发出消息的)link()机制没有静态生命周期。Context

在理想的情况下,提交给闭包的值可以仅作为 Yew 组件消息应用:

struct Model {
    thing: Option<JsValue>,
}

enum Msg {
    GotThing(JsValue),
}

#[wasm_bindgen]
extern "C" {
    fn createThing(closure: &Closure<dyn …
Run Code Online (Sandbox Code Playgroud)

closures callback rust wasm-bindgen yew

7
推荐指数
0
解决办法
757
查看次数

如何使用 wasm-bindgen 调用作为模块的 JavaScript 函数?

我正在尝试使用 Rust 中的 Web3 JavaScript 库,但我陷入了困境。该库的标准用法始于:

// In Node.js use: const Web3 = require('web3');

let web3 = new Web3(Web3.givenProvider || "ws://localhost:8545");
Run Code Online (Sandbox Code Playgroud)

您应该导入的模块是一个构造函数,它还有一些其他属性。我的 Rust 代码应该绑定这个 API,如下所示:

#[wasm_bindgen(module = "web3")]
extern "C" {
    type Web3;

    #[wasm_bindgen(constructor)]
    fn new(_: &Provider) -> Web3;

    type Provider;

    static givenProvider: Provider;
}
Run Code Online (Sandbox Code Playgroud)

最终输出import { Web3, givenProvider } from 'web3';并尝试运行new Web3(...)失败。它应该执行诸如import * as Web3 from 'web3';运行new Web3(...)和引用之类的操作Web3.givenProvider

我怎样才能让 wasm-bindgen 输出这样的代码?

rust webassembly wasm-bindgen

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