摆脱生成的 JavaScript 并直接执行 WebAssembly

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

我计划为 NodeJS 创建一个使用本机代码的库,这次我想尝试一下 WebAssembly。目前,我可以将 C 代码编译为 WebAssembly,但 Emscripten 会生成一个

.wasm
和一个
.js
文件。我知道幕后涉及一个运行时,但我想知道是否没有办法加载 WebAssembly(如下所列)并调用该函数。

我的主要.c

#include <stdio.h>
#include <emscripten/emscripten.h>

EMSCRIPTEN_KEEPALIVE
extern void hello() {
  printf("Hello world!\n");
}

我的index.js

var a = require("./a.out.js");

a().then((instance) => {
  instance.ccall("hello"); // Prints "Hello World!"
});

编译

emcc -s NO_EXIT_RUNTIME=1 -sMODULARIZE -s "EXPORTED_RUNTIME_METHODS=['ccall']" main.c

奔跑

node index.js 

以上有效。下面的代码没有

const fs = require("node:fs");

const wasmBuffer = fs.readFileSync("a.out.wasm");
WebAssembly.instantiate(wasmBuffer).then((wasmModule) => {
  const { hello } = wasmModule.instance.exports;
  hello();
});

错误

node index.js
node:internal/process/promises:288
            triggerUncaughtException(err, true /* fromPromise */);
            ^

[TypeError: WebAssembly.instantiate(): Imports argument must be present and must be an object]

Node.js v18.18.2
javascript node.js webassembly emscripten
1个回答
0
投票

如果您的目标是 Node.js(而不是浏览器 JavaScript),我强烈建议您采用本机 Node-API 路线。它速度更快,有更好的支持,并且是一个非常成熟的环境。 WASM 仍然是一项稍微实验性的技术,有许多粗糙的地方。如果你不打算在浏览器中运行你的项目,那么你只能输给 WASM。

emscripten 依赖于一个特殊的加载器,因为它在创建时,WASM 没有指定的环境。这意味着 JavaScript 和 WASM 之间有很多粘合代码,而 emscripten 按照自己的方式行事。

今天有 WASI,它将成为未来的标准,但它仍处于起步阶段。它将通过为 WASI 软件指定标准环境和 ABI 来解决此类问题。

你不能直接加载 WASM,除非你愿意手动完成 emscripten 加载器所做的一切 - 我向你保证这并不容易 - 特别是如果你想要良好的跨平台兼容性。

© www.soinside.com 2019 - 2024. All rights reserved.