Rust wasm32未知数学函数未链接
我正在尝试新的wasm32 unknown target for Rust,我在调用数学函数时遇到问题(例如sin、cos、exp、atan2) Cargo.toml:Rust wasm32未知数学函数未链接,rust,webassembly,Rust,Webassembly,我正在尝试新的wasm32 unknown target for Rust,我在调用数学函数时遇到问题(例如sin、cos、exp、atan2) Cargo.toml: [package] name = "wasm_math" version = "0.1.0" authors = ["..."] [lib] path = "src/lib.rs" crate-type = ["cdylib"] [dependencies] src/lib.rs: #[no_mangle] pub ext
[package]
name = "wasm_math"
version = "0.1.0"
authors = ["..."]
[lib]
path = "src/lib.rs"
crate-type = ["cdylib"]
[dependencies]
src/lib.rs:
#[no_mangle]
pub extern "C" fn invoke_sin(x: f64) -> f64 {
x.sin()
}
index.html:
<!doctype html>
<html lang="en">
<head><meta charset="utf-8"><title>Wasm Math</title></head>
<body></body>
<script>
const imports = { env: { } };
fetch("target/wasm32-unknown-unknown/release/wasm_math.wasm").then(response =>
response.arrayBuffer()
).then(bytes =>
WebAssembly.instantiate(bytes, imports)
).then(results => {
alert(results.instance.exports.invoke_sin(1.0));
});
</script>
</html>
在firefox中打开html文件时,出现以下错误:
LinkError: import object field 'sin' is not a Function
我的设置有问题吗?或者这是Rust/WebAssembly/Firefox的一个缺点?我可以手动将sin
函数添加到javascript中的imports.env
对象中,但这似乎非常不容易,我必须为我使用的每个数学函数都这样做。有更好的办法吗
我使用的是nightly Rust工具链(nightly-x86_64-unknown-linux-gnu rustc 1.24.0-nightly(cddc4a62d 2017-12-26))和Firefox 57.0.1(64位)。根据sin
的说法,不包括在内
•WebAssembly不包含自己的数学函数,如sin、cos、exp、pow等。WebAssembly对这些函数的策略是允许它们作为库例程在WebAssembly本身中实现(请注意,x86的sin和cos指令既慢又不精确,目前通常都是避免的)。希望在WebAssembly上使用更快更不精确的数学函数的用户只需选择一个数学库实现即可
Rust似乎依赖LLVM来提供sin
(),但它对WASM没有这样做。我认为LLVM应该将其作为其LLVM.sin.f64
内在特性的一部分提供,但它们似乎不能保证每个目标的实现(强调我的目标):
这是一个重载的内在函数。您可以在任何浮点或浮点类型的向量上使用llvm.sin但并非所有目标都支持所有类型。
也许,考虑到这一点,锈病应该考虑执行<代码> S< <代码>本身。 < P> Kyle是诊断上的当务之急。我将补充两条建议
我知道您说过不想手动将
Math
函数添加到导入对象,但这样做并不太糟糕:
让mathImports={};
for(让对象名为getOwnPropertyNames(数学))
if(数学类型[名称]=“函数”)
mathImports[name]=数学[name];
棘手的事情是在常规导入之前弄清楚如何做(这样它们就不会覆盖您已经拥有的任何内容),并弄清楚要将导入放入哪个模块中(因为WebAssembly导入有一个名称空间,规范会调用模块
,然后在错误消息中看到一个字段
,所以Safari中的错误消息将同时包含模块
和字段
)
您可以将C库的一个子集构建到WebAssembly中,并将其用作导入对象的一部分。我有一个可用的端口。构建和使用它,构建说明
同样,将其值放入导入对象很难做到正确。我将使用迭代模块的导出,并确保名称损坏是正确的(看起来您的代码直接预期sin
,并且通常C名称在开始时会被一个额外的下划线损坏)。然后和上面一样,将它们添加到导入对象中,并获得正确的模块
/字段。作为另一种选择,您可以查看emscripten如何实现trig函数。实际上非常简单,下面是通过多项式实现的sin
LinkError: import object field 'sin' is not a Function