Javascript WebAssembly链接器模块=“env”

Javascript WebAssembly链接器模块=“env”,javascript,webassembly,Javascript,Webassembly,我正在运行教程,现在我想从我自己的页面运行hello.wasm。 我正在按照教程的说明编译代码 在我的index.html中,我正在执行以下操作: const instantiate = (bytes, imports = {}) => WebAssembly.compile(bytes).then(m => new WebAssembly.Instance(m, imports) ) fetch('hello.wasm') .then(response =&g

我正在运行教程,现在我想从我自己的页面运行hello.wasm。 我正在按照教程的说明编译代码

在我的index.html中,我正在执行以下操作:

const instantiate = (bytes, imports = {}) =>
  WebAssembly.compile(bytes).then(m =>
    new WebAssembly.Instance(m, imports)
  )

fetch('hello.wasm')
  .then(response => response.arrayBuffer())
  .then(bytes => instantiate(bytes, {}))
但我得到了这个错误:

因此,我尝试从中使用WebAssembly.Instance,并使用以下代码:

const instantiate = (bytes, imports = {}) =>
  WebAssembly.compile(bytes).then(m =>
    WebAssembly.instantiate(m, imports)
  )
我得到了一个不同的答案:


知道如何修复它吗?

显然,您的示例模块想要从名为env的模块导入一些东西。但是,您提供的导入对象为空。要使模块的实例化成功,您需要提供一个形式为{env:{…}的imports对象,其中点是对应于从env进行的每个导入的属性。

您的问题不清楚,但进一步的注释说明您将导入对象保留为{},导致实例化失败。WebAssembly使用双名称空间,其中实现了WebAssembly.Module的。每个导入都是module+field+kind,JavaScript导入对象必须实现这一点


Emscripten已经生成HTML+JS,为您加载hello.wasm,包括WebAssembly导入对象。Emscripten生成的内容非常大,因为它模拟操作系统。import对象提供对JavaScript的所有系统调用。您必须将这些信息传递给示例才能工作。。。或者只使用Emscripten已经生成的脚本

您正在使用的代码需要一个名为env的模块。Emscripten包含以下代码:

let importObject = {
  env: { foo: () => 42, bar: () => 3.14 }
};
这就是我前面提到的双名称空间:env是一个模块,foo/bar是字段。它们的类型是函数。WebAssembly支持其他类型的导入和导出:表、内存和全局


缺少单个模块或模块字段,或类型不匹配,都会导致实例化失败。

让我们尝试缩小问题范围:在第二个示例中,您不需要编译,只需实例化:它使用.wasm字节并编译+实例化它们。导入对象是什么?还是将其保留为默认值{}?我假设您的模块从Emscripten声明的导入是什么?即使我使用实例化的重载方法,它也会失败,并出现相同的错误。我正在将一个空对象作为导入传递给它,我不知道需要什么依赖项。Emscripten已经生成HTML+JS,为您加载hello.wasm,包括WebAssembly导入对象。Emscripten生成的内容非常大,因为它模拟操作系统。import对象基本上提供了对JavaScript的所有系统调用。您必须将这些信息传递给示例才能工作。。。或者只使用Emscripten已经生成的内容。我认为您的评论和@Andreas answer应该是正确的答案。太好了,我用额外的信息回答了!是的,我也这么认为。但是我怎样才能得到这些依赖关系呢?现在我正在尝试反编译wasm,看看导入语句是什么。我更新了我的问题,直接引用了教程中包含的Emscripten。虽然您的答案基本正确,但我认为应该用JF Bastien的评论来完成,JF Bastien的评论更为具体,对将来的参考很有用。@Bastien,WASM模块可以调用imperoObject.env中定义的函数吗?如果可能怎么办?