1

I have C code which returns a void* and size_t length to Javascript running in a web worker. In Javascript i have the following

let start = getStartAddress();
let len = getLength();

I know for Strings i can do

let mystring = UTF8ToString(start);

This is documented https://emscripten.org/docs/api_reference/preamble.js.html#conversion-functions-strings-pointers-and-arrays

I am at a total loss as to how i get an Uint8Array that i can send through postMessage.

Where would i find documentation that tells me how to do that?

In the absence of documentation an answer to my question would suffice.

  • _"I am at a total loss as to how i get an `Uint8Array` that i can send through `postMessage`."_ - hang on, what's going on here? Why do you need to use `Uint8Array` in JS? Do you want the JS to allocate first, or the C code to allocate firsty? What is the technical problem **exactly**? – Dai Sep 02 '22 at 10:26
  • Anyway, have you reviewed [the documentation for `ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer)? It can represent `UInt8Array` arrays and [it's a _transferrable object_](https://developer.mozilla.org/en-US/docs/Glossary/Transferable_objects) which can safely be used with `postMessage` and other browser APIs without issue. – Dai Sep 02 '22 at 10:28
  • Simply there might not be a convenience function for that. But you should be able to access [`buffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Memory/buffer), and make a copy of its contents. I can't tell if there's no simpler way now, but see my experiment with wasm from 4 years ago here: https://stackoverflow.com/questions/51666736/how-do-i-use-a-c-library-in-a-rust-library-compiled-to-webassembly/51804070#51804070 - I simply access `e.memory.buffer`, where `e=instance.exports`, comes from the instantiated wasm module. – tevemadar Sep 02 '22 at 10:43
  • However you definitely don't want to transfer the `buffer` of the module, but make a copy of what you need. And remember while you are making the copy you will likely use a typed array (like most probably a `Uint8Array`), but what you can transfer is the underlying `ArrayBuffer`. – tevemadar Sep 02 '22 at 10:48
  • @Dai I simply want to send the bytes through postMessage which already makes a copy. It seemed Uint8Array was the way to go. As a said, i'm not finding any docs and tapping in the dark. – Mario Theodoridis Sep 02 '22 at 11:32
  • It would help if you could show us how you're intending to use `postMessage`, exactly. – Dai Sep 02 '22 at 11:35

1 Answers1

0

Ok, so i actually found the definition for UTF8ToString in the Javascript file the emscripten compiler created for my .wasm file. I thought it was a native function. It calls UTF8ArrayToString in the same javascript file. Learning from that source code i came up with the following.

function BytesToArray(base, len) {
  let out = new Array(len);
  let i = 0, ptr = base, end = base + len;
  while (ptr < end) {
    out[i] = HEAPU8[ptr];
    i++;
    ptr++;
  }
  return out;
}
let mydata = BytesToArray(start, len);
postMessage(mydata);

I hope the performance isn't too bad.