web-dev-qa-db-ja.com

node.jsからWebAssemblyを使用する方法

私は現在、(実行時間を改善するために)Cサブルーチンを呼び出す必要がある個人用Node.js(> = 8.0.0)プロジェクトに取り組んでいます。ブラウザで開いたときに互換性のある最終コードが必要なので、これを行うためにWebAssemblyを使用しようとしています。

Emscriptenを使用してCコードをWebAssemblyにコンパイルしましたが、その後の手順がわかりません。

正しい方向への助けがあれば素晴らしいでしょう。ありがとう!

8
Cheran Senthil

JS接着ファイルなしで.wasmファイル( standalone )を構築できます。誰かが同様の 質問 に答えました。

Test.cファイルを作成します。

int add(int a, int b) {
  return a + b;
}

スタンドアロンの.wasmファイルをビルドします。

emcc test.c -O2 -s WASM=1 -s SIDE_MODULE=1 -o test.wasm

Node.jsアプリで.wasmファイルを使用します。

const util = require('util');
const fs = require('fs');
var source = fs.readFileSync('./test.wasm');
const env = {
    memoryBase: 0,
    tableBase: 0,
    memory: new WebAssembly.Memory({
      initial: 256
    }),
    table: new WebAssembly.Table({
      initial: 0,
      element: 'anyfunc'
    })
  }

var typedArray = new Uint8Array(source);

WebAssembly.instantiate(typedArray, {
  env: env
}).then(result => {
  console.log(util.inspect(result, true, 0));
  console.log(result.instance.exports._add(9, 9));
}).catch(e => {
  // error caught
  console.log(e);
});

重要な部分は WebAssembly.instantiate() の2番目のパラメーターです。これがないと、エラーメッセージが表示されます。

TypeError:WebAssembly Instantiation:Imports引数が存在する必要があり、起動時にProcess._tickCallback(internal/process/next_tick.js:188:7)at Function.Module.runMain(module.js:695:11)にあるオブジェクトでなければなりません(bootstrap_node.js:191:16)at bootstrap_node.js:612:3

13
yushulx

@svenに感謝します。 (翻訳のみ)

test.c:

#include <emscripten/emscripten.h>

int EMSCRIPTEN_KEEPALIVE add(int a, int b) {
    return a + b;
}

コンパイル:

emcc test.c -O2 -s WASM=1 -s SIDE_MODULE=1 -o test.wasm

test.js:

const util = require('util');
const fs = require('fs');
var source = fs.readFileSync('./test.wasm');
const env = {
  __memory_base: 0,
  tableBase: 0,
  memory: new WebAssembly.Memory({
    initial: 256
  }),
  table: new WebAssembly.Table({
    initial: 0,
    element: 'anyfunc'
  })
}

var typedArray = new Uint8Array(source);

WebAssembly.instantiate(typedArray, {
  env: env
}).then(result => {
  console.log(util.inspect(result, true, 0));
  console.log(result.instance.exports._add(10, 9));
}).catch(e => {
  // error caught
  console.log(e);
});
1
Helmut Kemper