我收到以下错误消息:
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) 当使用Closures为 JavaScript 提供回调时,有什么更好的方法来避免释放它们?所述WASM-定义BindGen引导建议使用.forget,但承认其基本上泄漏内存。
通常我们会存储句柄以便稍后在适当的时候被删除,但现在我们希望它是一个全局处理程序,所以我们使用该
forget方法来删除它而不会使闭包无效。请注意,这是 Rust 中的内存泄漏,因此应该谨慎地进行!
它暗示将闭包存储到适合丢弃的时间。在alexcrichton对上一个问题的回答中,他提到...
[...] 如果它 [...] 只被调用一次,那么你可以使用
Rc/RefCell来删除Closure闭包本身的内部(使用一些内部可变性恶作剧)
但他没有提供这种方法的例子。
在封闭的文档也给出了参考关闭返回JavaScript的背景下,以让它处理时释放参考的例子。
如果我们
cb放在这里,它会在时间间隔过去时引发异常。相反,我们将句柄返回给 JS,以便 JS 可以决定何时取消间隔并释放闭包。
我还想象有一些方法可以#[wasm_bindgen]在公共函数上使用生命周期或宏等功能来避免这个问题,但我无法弄清楚如何做到这一点。
我的问题是,使用.forget从 Rust 传递回 JavaScript 的闭包有哪些替代方法,我能否请您查看每个正在使用的选项的简单示例?
我有一个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) 我正在尝试导出以下结构:
#[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) 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章 … |
如果您回答我关于 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) 假设我在 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) 我正在尝试弄清楚如何使用 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 …
这个问题是为 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) 我正在尝试使用 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 输出这样的代码?
wasm-bindgen ×10
rust ×9
webassembly ×7
closures ×2
javascript ×2
callback ×1
compilation ×1
emscripten ×1
rust-cargo ×1
typed-arrays ×1
vector ×1
yew ×1