简体   繁体   中英

Emscripten: Calling a C function that modifies array elements

I have a simple C function that modifies elements of an integer array. I can convert it to JavaScript using Emscripten (emcc) without problems. But when I call the function on a JS array, the values in it do not seem to change. Please help.

This is the C function definition:

/* modify_array.c */
void modify_array(int X[8]) {
  int i;
  for (i = 0; i < 8; ++i) {
    X[i] += 1;
  }
}

This is the command I used to transpile the C code to JS:

emcc modify_array.c -o modify_array.js -s EXPORTED_FUNCTIONS="['_modify_array']"

And this is the JavaScript (Node.js) code for invoking the transpiled JS code:

var mod = require("./modify_array.js");
var f = mod.cwrap("modify_array", "undefined", ["array"]);

var X = [0, 1, 2, 3, 4, 5, 6, 7];
var bytesX = new Uint8Array(new Int32Array(X).buffer);

/* Invoke the emscripten-transpiled function */
f(bytesX);


console.log(new Int32Array(bytesX.buffer));

After running the JS code, the buffer contains values that are identical to the original values, not the incremented values. Why? How can I get the updated values?

Emscripten's memory model is a single flat array. That means that when you provide an array of data to a compiled C method, it is copied into the single array, which is the only place it can be accessed (the ccall/cwrap methods do this for you). In other words, all arguments you pass are by value, not by reference, even if they are arrays (which in JS normally are passed by reference).

To work within the emscripten memory model, you can use memory in the single flat array,

var ptr = Module._malloc(8);
var view = Module.HEAPU8.subarray(ptr, ptr+8);
var f = Module.cwrap("modify_array", "undefined", ["number"]);
f(ptr);

That reserves a space in the single array, and using a subarray on the single array, we can access its values. Note the use of number as the type. We are passing ptr , which is a pointer to the buffer. As a pointer, it is just a number referring to a location in the single array.

(Note that you should call free to release the memory at the right time.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM