这段代码几个月前就开始了,但现在它停止了工作,我无法弄清楚原因:
#[no_mangle]
pub fn simple_arr() -> *mut i32 {
let vec = &mut [111, 222, 333, 444];
return vec.as_mut_ptr();
}
fn main() {
println!("Hello, world!");
}
我正在使用以下工具编译代码:
$ cargo +nightly build --target wasm32-unknown-unknown --release
$ wasm-gc target/wasm32-unknown-unknown/release/wasm-examples.wasm m.wasm
然后启动HTTP服务器并在浏览器中运行以下代码:
fetch('m.wasm')
.then(r => r.arrayBuffer())
.then(r => WebAssembly.instantiate(r))
.then(m => window.m = m);
var HEAP32 = new Int32Array(m.instance.exports.memory.buffer);
var arrayPtr = m.instance.exports.simple_arr();
console.log(HEAP32[arrayPtr / Int32Array.BYTES_PER_ELEMENT]);
我得到0.即使我不断增加偏移量/指针,我仍然会得到0或随机数。
我无法弄清楚我错过了什么。
我也尝试过这种形式:
use std::os::raw::c_void;
#[no_mangle]
pub fn simple_arr() -> *mut c_void {
let mut vec = vec![100, 200, 300, 400];
vec.as_mut_ptr()
}
fn main() {
println!("Hello, world!");
}
但我仍然得到相同的结果。
我也尝试用Emscripten编译它,结果仍然相同。
更新
我尝试暴露一个静态字符串,并且有效(通过How to return a string (or similar) from Rust in WebAssembly?)。然而,暴露一个向量似乎不同,我不认为这个结果适用于我。
我尝试声明向量静态
#[no_mangle]
pub fn simple_arr() -> *mut c_void {
static mut vec: &'static [i32] = &[100, 200, 300, 400];
unsafe { vec.as_mut_ptr() as *mut c_void }
}
但我无法编译。
更新:我得到了它的工作!!
#[no_mangle]
pub fn simple_arr() -> *const i32 {
let vec = &[100, 200, 300, 400];
vec.as_ptr() as *const i32
}
据我了解,指针生命周期在函数执行后立即结束。因此,使用const,我们可以延长该指针的生命周期。
最终更新:
好的,所以最终的最终版本是从Boxed向量中公开一个包装指针:
#[no_mangle]
pub fn simple_arr() -> *mut i32 {
let vec = Box::new([100, 200, 300, 400]);
Box::into_raw(vec) as *mut i32
}
我希望这是"非偶然的"版。如果不是这样,请发表评论。
谢谢大家!