Accessing UInt8ClampedArray in Rust web assembly
我想将包含
JS
1 2 3 4 5 6 7 8 9 10 11 12 | 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); } |
锈
1 2 3 4 5 | #[no_mangle] pub fn print_image_data(data: *mut [u8]) -> i32 { println!("{:?}", data); 32 } |
执行此操作时,我在浏览器控制台中收到以下错误:
1 2 3 | 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重新访问该数据? 我读过,不可能传回数组。
编辑:
在emscripten的文档中,我发现了以下内容:
argTypes – An array of the types of arguments for the function (if there are no arguments, this can be omitted). Types are as in returnType, except that array is not supported as there is no way for us to know the length of the array).
还有另一种方法吗? 也许通过一个指针并以某种方式访问数组? 我发现很难找到文档,因此欢迎任何链接:)
基于此代码,这是访问
的JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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)}`); }); |
锈
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 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; } |