【问题标题】:Wasm: Uncaught (in promise) TypeError: Import #0 module="env" error: module is not an object or function Promise.then (async) (anonymous) @ (index):9Wasm: Uncaught (in promise) TypeError: Import #0 module="env" error: module is not an object or function Promise.then (async) (anonymous) @ (index):9
【发布时间】:2018-10-03 09:20:40
【问题描述】:

我是 emscripten 的新手,发现它很难...我有义务在 Windows 上工作,因为我必须测试我的应用程序的 .exe 版本。我在 Windows 7 上。

我可以编译 wasm 但 javascript 无法读取它。这是我的代码。

C 代码:

char * HelloWorld ()
{
    return "Hello World !";
}

Emscripten 命令行:

emcc hello.c -O2 -s ONLY_MY_CODE=1 -s WASM=1 -s SIDE_MODULE=1 -s EXPORTED_FUNCTIONS="['_HelloWorld']" -o hello.wasm

结果:

(module
  (type $t0 (func (result i32)))
  (type $t1 (func))
  (import "env" "memory" (memory $env.memory 256))
  (import "env" "memoryBase" (global $env.memoryBase i32))
  (func $_HelloWorld (export "_HelloWorld") (type $t0) (result i32)
    (get_global $env.memoryBase))
  (func $__post_instantiate (export "__post_instantiate") (type $t1)
    (set_global $g1
      (i32.add
        (get_global $env.memoryBase)
        (i32.const 16)))
    (set_global $g2
      (i32.add
        (get_global $g1)
        (i32.const 5242880))))
  (global $g1 (mut i32) (i32.const 0))
  (global $g2 (mut i32) (i32.const 0))
  (data (get_global $env.memoryBase) "Hello World !"))

Javascript:

importObject = {};

fetch('hello.wasm').then(response =>
  response.arrayBuffer()
).then(bytes =>
  WebAssembly.instantiate(bytes, importObject)
).then(results => {
  console.log("loaded");
});

错误信息:

Uncaught (in promise) TypeError: Import #0 module="env" error: module is not an object or function
Promise.then (async)
(anonymous) @ (index):9

你能告诉我我的代码有什么问题吗?

【问题讨论】:

    标签: javascript c emscripten webassembly


    【解决方案1】:

    我认为挑战在于:WebAssembly 还没有完全成熟。

    这些示例显示了它们的加载器来自看起来像 NPM 包的内容。在那个包中,importObj 是可选的。

    你和我正在尝试使用 WebAssembly.instantiate() - 我正在使用网络工作者。

    所以我们需要传递一个更完整的导入——特别是一个带有 abort 方法的 env。这是来自https://webassembly.studio 的汇编脚本启动项目的示例:

    main.html

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
    </head>
    <body style="background: #fff">
      <span id="container"></span>
      <script src="./main.js"></script>
    </body>
    </html>
    

    main.js

    WebAssembly.instantiateStreaming(fetch("../out/main.wasm"), {
      main: {
        sayHello() {
          console.log("Hello from WebAssembly!");
        }
      },
      env: {
        abort(_msg, _file, line, column) {
          console.error("abort called at main.ts:" + line + ":" + column);
        }
      },
    }).then(result => {
      const exports = result.instance.exports;
      document.getElementById("container").textContent = "Result: " + exports.add(19, 23);
    }).catch(console.error);
    

    main.ts

    declare function sayHello(): void;
    
    sayHello();
    
    export function add(x: i32, y: i32): i32 {
      return x + y;
    }
    

    注意 importObject 中的 env.abort 函数

    【讨论】:

    • C 和 emscripten 的问题)
    • 我猜这个问题由于它的年龄而不再实际
    • 搜索那个错误会带来这篇文章。此错误与尝试将 AssemblyScript 加载器示例与 WebAssembly 浏览器实例化时相同。问题不是 C/emscripten,它没有正确填写 importObj。如果有更多示例可供参考,那将非常有帮助。
    【解决方案2】:

    你应该这样写 importObject

    const importObject = {
      env: {
        __memory_base: 0,
        __table_base: 0,
        memory: new WebAssembly.Memory({initial: 1})
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-03-25
      • 1970-01-01
      • 2017-04-13
      • 1970-01-01
      • 1970-01-01
      • 2020-03-17
      • 2020-01-06
      • 2021-03-10
      • 2021-09-30
      相关资源
      最近更新 更多