【问题标题】:Emscripten: Calling a C function that modifies array elementsEmscripten:调用修改数组元素的 C 函数
【发布时间】:2015-03-27 23:20:02
【问题描述】:

我有一个简单的 C 函数,可以修改整数数组的元素。我可以使用 Emscripten (emcc) 毫无问题地将其转换为 JavaScript。但是当我在 JS 数组上调用函数时,其中的值似乎没有改变。请帮忙。

这是 C 函数定义:

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

这是我用来将 C 代码转换为 JS 的命令:

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

这是调用转译后的 JS 代码的 JavaScript (Node.js) 代码:

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));

运行 JS 代码后,缓冲区包含与原始值相同的值,而不是增量值。为什么?如何获取更新的值?

【问题讨论】:

  • 你不应该在 C 中传递一个指针和一个数组大小吗?
  • @zerkms:我尝试了 C 函数签名 modify_array(int *X, int size),然后再次执行 emscripten 工作流程,当然还有对 JavaScript 语法的修改。该行为似乎与原始的基于数组的 C 函数签名完全相同。
  • 你能显示modify_array.js的内容吗?
  • @zerkms,感谢您的建议。但我看不出这有什么帮助。生成的文件非常大(9.8k 行)并且代码不是很可读。如果你愿意,我可以 PM 给你(如果 StackOverflow 上有这样的话)。
  • 没错,@zerkms。这显然是 Emscripten 的工作原理......在 StackOverflow 上进行了更多搜索(我可能应该事先完成),我发现了这个 Q+A:stackoverflow.com/questions/17883799/…。这解决了我的问题。使用 Module._malloc 创建一块堆内存,将 JS 参数指定为“数字”并将其传递给 JS 函数就可以了。稍后您可以使用“getValue”或“subArray”在同一堆内存位置检索新值。

标签: javascript c arrays node.js emscripten


【解决方案1】:

Emscripten 的内存模型是单个平面数组。这意味着当您向已编译的 C 方法提供数据数组时,它会被复制到单个数组中,这是唯一可以访问它的地方(ccall/cwrap 方法会为您执行此操作)。换句话说,您传递的所有参数都是按值而不是按引用,即使它们是数组(在 JS 中通常是按引用传递)。

要在 emscripten 内存模型中工作,您可以在单个平面数组中使用内存,

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

这在单个数组中保留了一个空间,并且使用单个数组上的子数组,我们可以访问它的值。注意使用number 作为类型。我们传递了ptr,它是一个指向缓冲区的指针。作为一个指针,它只是一个引用单个数组中某个位置的数字。

(注意,你应该在适当的时候调用free释放内存。)

【讨论】:

  • Module.malloc 对我不起作用,但 Module 有 '_malloc',它似乎工作正常
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-04
  • 2019-02-17
  • 1970-01-01
相关资源
最近更新 更多