javascript-如何在Rust和WebAssembly中解析函数指针
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了javascript-如何在Rust和WebAssembly中解析函数指针,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2595字,纯文字阅读大概需要4分钟。
内容图文
我想为WebAssembly模块提供一个接受Rust函数指针的外部JavaScript函数.
初始化此JS模块后,它将从.wasm模块调用run()函数,然后依次调用peekaboo:
window.Module = {};
const imports = {
env: {
memoryBase: 0,
tableBase: 0,
memory: new WebAssembly.Memory({ initial: 256 }),
table: new WebAssembly.Table({ initial: 4, element: 'anyfunc' })
}
};
imports.env.peekaboo = function(f) {
const fn = imports.env.table.get(f);
return fn(2);
};
fetch('game.wasm')
.then(response => response.arrayBuffer())
.then(bytes => WebAssembly.compile(bytes))
.then(mod => WebAssembly.instantiate(mod, imports))
.then(mod => {
mod.exports.run();
Module.memory = imports.env.memory;
Module.dealloc_str = mod.exports.dealloc_str;
});
我看到的示例表明,如果我以这种方式导入内存,则应该能够使用表来解析函数指针.这是Rust代码:
#![feature(wasm_import_memory)]
#![wasm_import_memory]
extern "C" {
fn peekaboo(f: fn(u32) -> u32);
}
fn main() {}
#[no_mangle]
pub fn run() {
let plus_one = |x: u32| -> u32 { x + 1 };
unsafe {
peekaboo(plus_one);
}
}
一切都可以正常编译,但是当我执行peekaboo函数时,fn变量为null,表明表无法找到函数指针.因此,执行fn(2)会导致:
Uncaught (in promise) TypeError: fn is not a function
我或多或少遵循了this example,但是由于我在Rust中工作,所以翻译不是一对一的.我怀疑我忽略了一些对我来说并不明显的东西,因为我对Rust和WebAssembly都是新手.谁能发现我的错误?
解决方法:
到目前为止,Rust中的WebAssembly后端似乎还没有提供导入或导出(功能)表的方式;索引f很好,但是import.env.table与wasm实例使用的表不同(即为空).
另外,您应该在FFI中使用extern fn.
如果您想了解一下Playground提供了一些不错的WebAssembly优化,请查看以下示例:
#![crate_type = "cdylib"]
#![feature(link_args)]
#![allow(unused_attributes)] // link_args actually is used
#![link_args = "--import-memory"]
extern "C" {
fn peekaboo(f: extern "C" fn(u32) -> u32);
}
#[no_mangle]
pub fn run() {
extern "C" fn plus_one(x: u32) -> u32 {
x + 1
}
unsafe {
peekaboo(plus_one);
}
}
结果应如下所示:
(module
(type $t0 (func))
(type $t1 (func (param i32) (result i32)))
(type $t2 (func (param i32)))
(import "env" "peekaboo" (func $peekaboo (type $t2)))
(import "env" "memory" (memory $env.memory 17))
(func $run (export "run") (type $t0)
(call $peekaboo
(i32.const 1)))
(func $playground::run::plus_one::h85275af105f0cc85 (type $t1) (param $p0 i32) (result i32)
(i32.add
(get_local $p0)
(i32.const 1)))
(table $T0 2 2 anyfunc)
(elem (i32.const 1) $playground::run::plus_one::h85275af105f0cc85))
如果要在本地复制,请在Cargo.toml中添加:
[lib]
crate-type = ["cdylib"]
[profile.release]
lto = true
并使用每晚构建货物–release –target wasm32-unknown-unknown进行构建(假设使用夜间工具链的rustup设置和为夜间工具链启用的wasm32-unknown-unknown目标).
内容总结
以上是互联网集市为您收集整理的javascript-如何在Rust和WebAssembly中解析函数指针全部内容,希望文章能够帮你解决javascript-如何在Rust和WebAssembly中解析函数指针所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。