Emscripten 切换双数组 - 显然收到随机地址

问题描述 投票:0回答:1

我无法将双数组移交给通过 emscripten 生成的 WASM 文件。我已将其生成为 WASM=1 的 .js 输出文件,因此我还有一个 wasm 文件。

这是我的缩写 C++ 代码:

#include <iostream>
using namespace std;

extern "C" {

  int main(int argc, char** argv) {
    return 0;
  }

  double *calculate(double *x, double *y, int array_length) {
    std:cout << "Array Length: " << array_length << endl;
    for (int i = 0; i < array_length; i++) {
      std::cout << "Coords: " << x[i] << ", " << y[i] << endl;
    }
    return new double[7]{1,1,2,3,5,8,13};
  }
}

它在浏览器控制台中生成以下输出:

Array Length: 4 average.js:8:16057
Coords: 2.36377e+232, 2.36377e+232 average.js:8:16057
Coords: 5.9419e-310, 5.9419e-310 average.js:8:16057
Coords: 4.28375e-319, 4.28375e-319 average.js:8:16057
Coords: 1.4854e-313, 1.4854e-313

我可以看到它做了一些事情。

这是调用它的代码:

import { CalculationAdapterInterface, Coords, GraphData } from "../CalculationAdapterInterface";
import averageModule from "./average"

export default class CalculationWasmAdapter implements CalculationAdapterInterface {
  

  async calculate(data: GraphData): Promise<Coords|void> {
    
    const x = [ 5.0, 3.0, 2.0, 5.0];
    const y = x.map(x => x/2);
    const to_byte = (arr: number[]) => { return new Float64Array(arr).buffer}

    const filePath = window.location.origin + "/average.wasm";
    averageModule({locateFile: () => filePath}).then((module: any) => {
      const calculate = module.cwrap('calculate', 'number', ['array', 'array', 'int'])
      calculate(to_byte(x), to_byte(y), x.length);
    })
  }
}

我不明白为什么会在浏览器中生成输出。 当我更改数组中的输入值时,它不会更改打印值(打印的数量除外)。我强烈怀疑 C++ 代码不接收数组并从某些默认分配的空间读取。但为什么呢?

c++ arrays typescript webassembly emscripten
1个回答
0
投票

我只做过一次,我并不声称自己是专家,但我使用这种技术成功地将双精度数组从 JavaScript 传递到 C++。

我的理解是,如果你想从 JavaScript 访问内存,你必须意识到 JavaScript 和 WebAssembly 具有不同的内存布局。您可以使用 HEAPF64.set

 将数据从 JavaScript 数组(具有自己的内存布局)复制到 Emscripten HEAP,WebAssembly 模块可以在其中访问数据。

这是我的示例,它是node.js(抱歉,这就是我使用它的方式),但在浏览器平台中应该可以实现类似的操作。

const factory = require('./src/passarray.js'); factory().then(instance => { const doubleArray = new Float64Array([1.0, 2.0, 3.0, 4.0, 5.0]); const arrayPointer = instance._malloc(doubleArray.length * doubleArray.BYTES_PER_ELEMENT); instance.HEAPF64.set(doubleArray, arrayPointer / doubleArray.BYTES_PER_ELEMENT); instance._exampleFunction(arrayPointer); instance._free(arrayPointer); });
在C++方面:

extern "C" { EMSCRIPTEN_KEEPALIVE void exampleFunction(double* elems) { // [your code here] } }
    
© www.soinside.com 2019 - 2024. All rights reserved.