我从这个Rust代码创建了一个小的Wasm文件:
#[no_mangle]
pub fn hello() -> &'static str {
"hello from rust"
}
字符串
它可以构建,并且可以从JS调用hello
函数:
<!DOCTYPE html>
<html>
<body>
<script>
fetch('main.wasm')
.then(response => response.arrayBuffer())
.then(bytes => WebAssembly.instantiate(bytes, {}))
.then(results => {
alert(results.instance.exports.hello());
});
</script>
</body>
</html>
型
我的问题是alert
显示“undefined”。如果我返回一个i32
,它会工作并显示i32
。我也试图返回一个String
,但它不工作(它仍然显示“undefined”)。
有没有办法在WebAssembly中从Rust返回一个字符串?我应该使用什么类型?
4条答案
按热度按时间at0kjp5o1#
WebAssembly只支持一些数字类型,这是所有可以通过导出函数返回的类型。
当你编译到WebAssembly时,你的字符串将保存在模块的线性内存中。为了从宿主JavaScript中读取这个字符串,你需要返回一个对它在内存中的位置的引用,以及字符串的长度,即两个整数。这允许你从内存中读取字符串。
无论您使用哪种语言编译WebAssembly,都可以使用相同的技术。How can I return a JavaScript string from a WebAssembly function提供了该问题的详细背景。
对于Rust,你需要使用外部函数接口(FFI),使用
CString
类型,如下所示:字符串
上面的代码导出了两个函数,
get_hello
返回字符串的引用,get_hello_len
返回字符串的长度。将上述代码编译为wasm模块后,可以按如下方式访问字符串:
型
C等价物can be seen in action in a WasmFiddle。
qmelpv7a2#
从Rust fn返回字符串到ReactApp
TLDR:
添加到main.rs
use wasm_bindgen::prelude::*;
使用
JsValue
作为fn的返回类型。从fn
JSValue::from_str("string")
返回为函数创建Rust库
创建React App演示Rust函数
型
App.js
型
启动应用
型
Hello from rust, Human!
个mbzjlibv3#
不能直接返回Rust
String
或&str
。而是分配并返回一个原始字节指针,其中包含数据,然后必须在JavaScript端编码为JS字符串。你可以看看SHA1的例子here。
感兴趣的功能是
demos/bundle.js
-copyCStr
demos/sha1/sha1-digest.rs
-digest
更多示例:https://www.hellorust.com/demos/sha1/index.html
biswetbf4#
我看到的大多数例子都复制了两次字符串。首先在WASM端,复制到
CString
中,或者将Vec
缩小到它的容量,然后在JS端解码UTF-8。考虑到我们经常为了速度而使用WASM,我试图实现一个重用Rust向量的版本。
字符串
JavaScript部分:
型
这里的代价是,我们在WASM中使用
HashMap
,这可能会增加大小,除非已经需要HashMap
。一个有趣的替代方案是使用tables与JavaScript共享(payload,length,capacity)三元组,并在释放字符串时将其取回。
P.S.有时候我们并不想一开始就分配
Vec
。在这种情况下,我们可以将内存跟踪移动到JavaScript:
的字符串