'Passing arrays and objects from JavaScript to c++ in Web Assembly

Ok, I've been pounding against this for a bit. I'm more of a JavaScript and C# focused dev, but I have some experience in c++. My problem is

  1. I need to find a simple way to take a Javascript object and pass it through WebAssembly to c++
  2. I need to do the same with Javascript arrays
  3. I probably need to do the same with Javascript arrays of Javascript objects

So starting with what I have tried on a simple array:

//c++
int testArr(int * arrIn, int length){
  int results = 0;
  for(int i = 0; i < length; i++){
    results += arrIn[i] + 1;
  }
  return results;
}


//javascript
let arr = [20, 50, 90, 62, 98];
console.log(wasmInstance.exports.testArr(arr, arr.length));

So that should take an array of integers, add them plus 1 (basically to test the loop). It returns 5. I expect it to return 325. So looking at typed arrays was the next logical step...

//c++
int testArr(int * arrIn, int length){
  int results = 0;
  for(int i = 0; i < length; i++){
    results += arrIn[i] + 1;
  }
  return results;
}


//javascript
let arr = [20, 50, 90, 62, 98];
let typedArray = new Int32Array(arr);

//test 1
console.log(wasmInstance.exports.testArr(typedArray, arr.length));

//test 2
console.log(wasmInstance.exports.testArr(typedArray.buffer, arr.length));

Test 1 returns, again, 5. Test 2 returns 0.

Now just to see if I can get c++ to return an array:

//c++
int * test(){
  int arr[] = {12, 32, 54, 31};
    return arr;
}

//Javascript
console.log(wasmInstance.exports.test());

Returns -16. Kind of funky and probably due to pointer issues between the two. Now if I try this:

//c++
int test(){
  int arr[] = {12, 32, 54, 31};
    return arr[0];
}

//Javascript
console.log(wasmInstance.exports.test());

Now it returns 12.

And so that is so far is as far as I have gotten on passing arrays, which for the most part does not seem possible. Now, passing objects. God help me. Please be kind on the c++ because its not my strongest language.

//c++
class Vector3{
  public:
    float x;
    float y;
    float z;
    
    Vector3(float X, float Y, float Z){
      x = X;
      y = Y;
      z = Z;
    }
};

int test(Vector3 position){
    return position.x;
}


//javascript
let position = {x: 21, y: 30, z: 12};
console.log(wasmInstance.exports.test(position));

This returns 0 instead of 21;

And now for the unholy trinity, an array of javascript objects...

//c++
class Vector3{
  public:
    float x;
    float y;
    float z;
    
    Vector3(float X, float Y, float Z){
      x = X;
      y = Y;
      z = Z;
    }
};

Vector3 test(Vector3 positions[], int length){
    return positions[0];
}


//javascript
let positions = [{x: 21, y: 30, z: 12},{x:15, y: 24, z: 14}]
console.log(wasmInstance.exports.test(positions, positions.length));

This returns undefined.

So the question is, am I messing up in c++, javascript, wasm, all 3, or what? I've spent 3 days scouring the internet looking for answers and the only thing I can find is declarations that this is possible with no examples or documentation to say HOW this can be done. The best documentation I've found is a DevRant, which still didn't give me an answer on this.

So is this possible and if so, are there any working examples I can follow OR is this not at all possible?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source