javascript - 当数组的类型不是 Uint8 时,如何从 Javascript 代码访问 asm.js 堆上的数组?

标签 javascript arrays asm.js

我正在尝试使用 emscripten 和 asm.js 来加速我的 Javascript 代码。我需要从 Int32Array 获取数据到我编译的 C 函数中。根据this Github site我可以分配一个缓冲区,将数据复制到其中,然后调用一个将该缓冲区的指针作为输入的函数,如下所示:

var buf = Module._malloc(myTypedArray.length*myTypedArray.BYTES_PER_ELEMENT);
Module.HEAPU8.set(myTypedArray, buf);
Module.ccall('my_function', 'number', ['number'], [buf]);
Module._free(buf);

但它对 Uint8Array 以外的任何东西都不起作用,因为 Uint8Array.set“有用”地将输入数组的数据类型转换为 Uint8 而不是只做一个原始副本。换句话说,如果我尝试使用此方法将 Int32Array.of(1, -1) 复制到地址 100 处的堆中,我将得到

{ ... 100:1, 101:255, 102:0, 103:0, 104:0, 105:0, 106:0, 107:0 ... }

代替

{ ... 100:1, 101:0, 102:0, 103:0, 104:255, 105:255, 106:255, 107:255 ... }

(假设是小端)

那么我应该如何将数据复制到 asm.js 堆中或从堆中复制数据呢?我知道 ArrayBuffer 对象可以按位转换为任何类型化数组类型,但似乎不可能反过来(更正:请参阅 Jaromanda X 的评论) .此外,我阅读、考虑并拒绝了网站的建议,尽可能选择 setValue/getValue 因为我有数百万的东西要复制,我想避免开销如果可能的话,每个函数调用一次。

最佳答案

事实证明我错了:可以将 Int32Array 转换为 ArrayBuffer,然后转换为 Uint8Array 原始 View 大批。下面是一个函数的完整示例,该函数总结了一个 int32_t 数组,实现为一个 JS 函数,将一个 int32_t 数组传递给一个 C 函数:

sum.c(编译成sum.c.js)

#include <stdint.h>
#include <stddef.h>

double sum_i32(const int32_t* ints, size_t count) {
    double result = 0.0;
    while (count-- > 0) {
        result += *ints++;
    }
    return result;
}

求和.js

"use strict";

const cModule = require("./sum.c.js");

module.exports.sum_i32 = function sum_i32(array) {
    // Convert to array of int32_t if needed.
    if (!(array instanceof Int32Array)) {
        array = new Int32Array(array);
    }
    // Allocate a buffer to store a copy of the input array.
    const ptr = cModule._malloc(array.length * 4);
    let result = NaN;
    if (ptr === 0) {
        throw "Out of memory";
    }
    try {
        // View int32_t array as uint8_t using the int array's ArrayBuffer.
        const u8view = new Uint8Array(array.buffer);
        // Copy it to the right position in the heap and call the C function.
        cModule.HEAPU8.set(u8view, ptr);
        result = cModule._sum_i32(ptr, array.length);
    } finally {
        cModule._free(ptr);
    }
    return result;
}

关于javascript - 当数组的类型不是 Uint8 时,如何从 Javascript 代码访问 asm.js 堆上的数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46842580/

相关文章:

javascript - 当焦点更改为 React Select 时,React Slate 中的文本选择不再标记

javascript - 如何使用已部署的 meteor 应用程序运行 mongo shell 脚本?

java - 删除数组中空值的最有效方法是什么。

javascript - asm.js Module.ccall/Module.cwrap 回调

javascript - JavaScript 对象的终结器

javascript - 在带有图例的引导模式中显示 donut /饼图

javascript - 正则表达式验证器 - 如何包含某些特殊字符

java - Java 的 ObjectOutputStream 的 writeObject() 方法如何用于数组?

Javascript正则表达式将字符串拆分为分组/连续字符数组

javascript - 在 OdinMonkey 中优化 asm.js