tonethar
tonethar

Reputation: 2282

emscriptem - how to read a C-array from JavaScript (Chrome/Firefox)?

Here's my C code:

// helloworld.c
#include <stdio.h>
#include <emscripten.h>

int* EMSCRIPTEN_KEEPALIVE getIntArray(){
    static int numbers[] = {1, 2, 4, 8, 16};
    return numbers;
}

Here's some of my JS:

// helloworld.html
let result = Module.ccall('getIntArray', // name of C function
  'Uint8Array', // return type
  [null], // argument types
  [null]); // arguments

let array = new Uint8Array(result,5);

console.log(result); // prints 1024
console.log(array); // prints Uint8Array(1024) [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … ]

All of this compiles and runs fine. The above code works fine for primitive values, but fails with the array pointer, and the JS typed array I get back is all zeros. I have seen some other solutions in the documentation, but they don't seem to work for me either.

Upvotes: 1

Views: 230

Answers (1)

ColinE
ColinE

Reputation: 70132

You getIntArray function is going to return an integer which is the location of the array in the WebAssembly modules linear memory. In order to use this, you will need a reference to the module's linear memory.

One option is to create the linear memory on the JavaScript side:

const imports = {
    env: {
      memoryBase: 0,
      tableBase: 0,
      memory: new WebAssembly.Memory({
        initial: 512
      }),
      table: new WebAssembly.Table({
        initial: 0,
        element: 'anyfunc'
      })
    }
  };

  const instance = new WebAssembly.Instance(module, imports);

You can then use the returned result, which will be an integer, as an offset into linear memory:

 const result = Module.ccall('getIntArray', // name of C function
  'Uint8Array', // return type
  [null], // argument types
  [null]); // arguments

  const data = new Uint8Array(imports.env.memory.buffer, result, 5);

Upvotes: 3

Related Questions