Emscripten WebAssembly:导出类“Import #13 module="GOT.func" 错误:模块不是对象或函数”
Posted
技术标签:
【中文标题】Emscripten WebAssembly:导出类“Import #13 module="GOT.func" 错误:模块不是对象或函数”【英文标题】:Emscripten WebAssembly: Exporting Class "Import #13 module="GOT.func" error: module is not an object or function" 【发布时间】:2021-01-28 23:10:37 【问题描述】:我一直在玩弄在项目中将 WebAssembly 用作可导入功能模块(希望最终在 React/Electron 应用程序中使用),所以我已经使用 Emscripten 设置自己并开始使用 C++ .
实现功能没有问题,但我的课程没有成功。我希望能够在 JS 中公开和实例化一个类并调用其上的方法,一直持续到“任务”完成。
下面是一个example from Emscripten's own website,它构建但在尝试运行时抛出错误(可能是由于我的构建命令和 JS 导入过程)
错误信息是[TypeError: WebAssembly.instantiate(): Import #13 module="GOT.func" error: module is not an object or function]
。
我想要实现的目标是否合理且可行?
#include <stdio.h>
#include <string>
#include <iostream>
#include <emscripten/emscripten.h>
#include <emscripten/bind.h>
using namespace emscripten;
class MyClass
public:
MyClass(int x, std::string y)
: x(x), y(y)
void incrementX()
++x;
int getX() const return x;
void setX(int x_) x = x_;
static std::string getStringFromInstance(const MyClass &instance)
return instance.y;
private:
int x;
std::string y;
;
// Binding code
EMSCRIPTEN_BINDINGS(my_class_example)
class_<MyClass>("MyClass")
.constructor<int, std::string>()
.function("incrementX", &MyClass::incrementX)
.property("x", &MyClass::getX, &MyClass::setX)
.class_function("getStringFromInstance", &MyClass::getStringFromInstance);
;
const util = require('util');
const fs = require('fs');
var source = fs.readFileSync('./dist/module.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('MODULE: ', result.instance.exports)
).catch(e =>
// error caught
console.log(e);
);
"name": "wasm-js-test",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts":
"build-test": "rm -rf ./dist && mkdir ./dist && em++ ./src/module.cpp -O2 -s WASM=1 -s SIDE_MODULE=1 --no-entry --bind -o ./dist/module.wasm && node test.js"
,
"author": "",
"license": "ISC"
【问题讨论】:
【参考方案1】:您可能不想使用-s SIDE_MODULE
。使用 SIDE_MODULE
启用您可能不想要的 emscripten 动态链接 (PIC) ABI。
使用--no-entry
和以.wasm
结尾的输出文件构建应该足以构建尽可能独立的东西。但是请记住,emscripten 的输出实际上是为由 emscripten 生成的 JS 运行而设计的,因此您可能会在尝试像这样自己加载它时遇到麻烦。
【讨论】:
您好,感谢您的快速回复!尝试删除-s SIDE_MODULE=1
,我收到错误[TypeError: WebAssembly.instantiate(): Import #13 module="wasi_snapshot_preview1" error: module is not an object or function]
现在您遇到了一个事实,即您需要实现模块所依赖的 API。您可以使用 wasm-objdump 或 wasm-dis 查看它需要哪些导入。然后,您将需要提供每个导入的实现。通常使用 emscirpten,您使用 -o <something>.js
构建,而 emscripten 将为您提供这些。
当我开始做教程时,我开始让 Emscripten 输出我通过 require() 导入的 JS 文件,但现在我试图导出一个类,我在文件。虽然我可以在 .wasm 文件中看到对应的字符串。我觉得我错过了什么
PROGRESS UPDATE:所以我能够使用命令 em++ ./src/testing.cpp -s --no-entry --bind -o ./dist/testing.js
构建类,并使用 onRuntimeInitialized
事件通过 JS 文件运行方法。我实际上并没有在很多地方看到这个引用。更改我想要 require() 我的 WASM 代码的方式,有什么办法可以避免这种情况?以上是关于Emscripten WebAssembly:导出类“Import #13 module="GOT.func" 错误:模块不是对象或函数”的主要内容,如果未能解决你的问题,请参考以下文章
如何表示来自 emscripten/webassembly 调用的 void* 返回
WebAssembly:将命名空间从 C++ 库导出到 JavaScript
将 QT WebAssembly 与 Emscripten 关联
快速上手 WebAssembly 应用开发:Emscripten 使用入门