我想将一个包含imageData
的数组从Canvas传递给Rust函数,以便用它进行一些计算。我已将返回类型设置为null,以获取单向数据传递给工作:
JS
wasm.initialize({ noExitRuntime: true }).then(module => {
const printImageData = module.cwrap("print_image_data", null, ["array"]);
const functions = { add, printImageData };
main(functions);
});
async function main(wasmFn) {
const imageData = await getImageData();
const data = new Uint8Array(imageData.data);
wasmFn.printImageData(data);
}
锈
#[no_mangle]
pub fn print_image_data(data: *mut [u8]) -> i32 {
println!("{:?}", data);
32
}
执行此操作时,我在浏览器控制台中收到以下错误:
thread 'main' panicked at 'cannot access stdout during shutdown', /checkout/src/libcore/option.rs:819:4
note: Run with `RUST_BACKTRACE=1` for a backtrace.
uncaught exception: 5261184
如何从Rust端访问数组?那我怎么能再从JavaScript访问这些数据呢?我已经读过,传回一个数组是不可能的。
修改
在the docs of emscripten我发现了以下内容:
argTypes - 函数参数类型的数组(如果没有参数,则可以省略)。类型与returnType一样,但不支持该数组,因为我们无法知道数组的长度。)
还有其他办法吗?也许通过指针并以某种方式访问数组?我觉得很难找到文档,所以任何链接都值得赞赏:)
答案 0 :(得分:1)
这是一种基于this code访问fetch('hello_world.gc.wasm')
.then(r => r.arrayBuffer())
.then(r => WebAssembly.instantiate(r))
.then(r => r.instance.exports)
.then(wasm => {
const width = 1;
const height = 1;
const byteSize = width * height * 4;
let pointer = wasm.alloc(byteSize);
let usub = new Uint8ClampedArray(wasm.memory.buffer, pointer, byteSize);
let img = new ImageData(usub, width, height);
wasm.abcd(pointer, width, height);
console.log(`${img.data[0].toString(16)}`);
console.log(`${img.data[1].toString(16)}`);
console.log(`${img.data[2].toString(16)}`);
console.log(`${img.data[3].toString(16)}`);
});
的方法。
<强>的JavaScript 强>
use std::mem;
use std::os::raw::c_void;
use std::slice;
// In order to work with the memory we expose (de)allocation methods
#[no_mangle]
pub extern "C" fn alloc(size: usize) -> *mut c_void {
let mut buf = Vec::with_capacity(size);
let ptr = buf.as_mut_ptr();
mem::forget(buf);
return ptr as *mut c_void;
}
#[no_mangle]
pub extern "C" fn dealloc(ptr: *mut c_void, cap: usize) {
unsafe {
let _buf = Vec::from_raw_parts(ptr, 0, cap);
}
}
#[no_mangle]
pub extern "C" fn abcd(pointer: *mut u8, width: usize, height: usize) {
let bytesize: usize = width * height * 4;
let sl = unsafe { slice::from_raw_parts_mut(pointer, bytesize) };
// Now you can change your buffer
sl[0] = 0xaa;
sl[1] = 0xab;
sl[2] = 0xac;
sl[3] = 0xad;
}
<强>锈强>
arangodb