gpt4 book ai didi

rust - 如何从 WebAssembly 中的 Rust 返回字符串(或类似字符串)?

转载 作者:行者123 更新时间:2023-12-03 11:48:17 31 4
gpt4 key购买 nike

我从这个 Rust 代码创建了一个小的 Wasm 文件:

#[no_mangle]
pub fn hello() -> &'static str {
"hello from rust"
}

它构建和 hello可以从 JS 调用函数:

<!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显示“未定义”。如果我返回 i32 ,它工作并显示 i32 .我还尝试返回 String但它不起作用(它仍然显示“未定义”)。

有没有办法在 WebAssembly 中从 Rust 返回一个字符串?我应该使用什么类型?

最佳答案

WebAssembly 只支持几个 numeric types ,这是可以通过导出函数返回的所有内容。

当您编译为 WebAssembly 时,您的字符串将保存在模块的线性内存中。为了从宿主 JavaScript 中读取该字符串,您需要返回对其在内存中位置的引用,以及字符串的长度,即两个整数。这允许您从内存中读取字符串。

无论您将哪种语言编译为 WebAssembly,您都使用相同的技术。 How can I return a JavaScript string from a WebAssembly function提供了问题的详细背景。

特别是对于 Rust,您需要使用外部函数接口(interface) (FFI),使用 CString键入如下:

use std::ffi::CString;
use std::os::raw::c_char;

static HELLO: &'static str = "hello from rust";

#[no_mangle]
pub fn get_hello() -> *mut c_char {
let s = CString::new(HELLO).unwrap();
s.into_raw()
}

#[no_mangle]
pub fn get_hello_len() -> usize {
HELLO.len()
}

上述代码导出两个函数, get_hello它返回对字符串的引用,以及 get_hello_len它返回它的长度。

将上述代码编译为 wasm 模块后,可以按如下方式访问字符串:
const res = await fetch('chip8.wasm');
const buffer = await res.arrayBuffer();
const module = await WebAssembly.compile(buffer);
const instance = await WebAssembly.instantiate(module);

// obtain the module memory
const linearMemory = instance.exports.memory;

// create a buffer starting at the reference to the exported string
const offset = instance.exports.get_hello();
const stringBuffer = new Uint8Array(linearMemory.buffer, offset,
instance.exports.get_hello_len());

// create a string from this buffer
let str = '';
for (let i=0; i<stringBuffer.length; i++) {
str += String.fromCharCode(stringBuffer[i]);
}

console.log(str);

C 等效 can be seen in action in a WasmFiddle .

关于rust - 如何从 WebAssembly 中的 Rust 返回字符串(或类似字符串)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62860967/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com