web-dev-qa-db-fra.com

Comment utiliser WebAssembly à partir de node.js?

Je travaille actuellement sur un projet Node.js personnel (> = 8.0.0) qui nécessite que j'appelle des sous-programmes C (pour améliorer le temps d'exécution). J'essaie d'utiliser WebAssembly pour ce faire car j'ai besoin que mon code final soit compatible lorsqu'il est ouvert dans un navigateur.

J'ai utilisé Emscripten pour compiler du code C dans WebAssembly, et je ne sais pas comment procéder après cela.

Toute aide dans la bonne direction serait formidable. Merci!

8
Cheran Senthil

Vous pouvez créer un fichier .wasm ( autonome ) sans fichier de colle JS. Quelqu'un a répondu à la même question .

Créez un fichier test.c:

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

Créez le fichier .wasm autonome:

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

Utilisez le fichier .wasm dans l'application Node.js:

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

La partie clé est le deuxième paramètre de WebAssembly.instantiate () . Sans cela, vous obtiendrez le message d'erreur:

TypeError: WebAssembly Instantiation: l'argument Imports doit être présent et doit être un objet at at process._tickCallback (internal/process/next_tick.js: 188: 7) at Function.Module.runMain (module.js: 695: 11) au démarrage (bootstrap_node.js: 191: 16) sur bootstrap_node.js: 612: 3

13
yushulx

Merci @sven. (traduire uniquement)

test.c:

#include <emscripten/emscripten.h>

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

compilation:

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);
});
0
Helmut Kemper