使用 JS 值的 WebAssembly C++ - 导入 #0 module="env": 模块不是对象或函数

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

我是 WebAssembly 的新手,我正在做一些实验。

我设法创建了非常简单的示例。

现在我想尝试在我的 C++ 代码中使用 JS 对象。具体来说,

我想尝试打印从窗口检索的元素,例如 C++ 代码中的位置。

这是我的 C++ 代码:

#include <string>
#include <emscripten.h>
#include <emscripten/val.h>

using namespace emscripten;

EMSCRIPTEN_KEEPALIVE
std::string decode_request(val window) {
    val location = window["location"];
    std::string search = location["search"].as<std::string>();
    size_t pos = search.find('?');
    if (pos != std::string::npos) {
        return search.substr(pos + 1);
    } else {
        return "";
    }
}

extern "C" {
    EMSCRIPTEN_KEEPALIVE
    const char* myFunction() {
        val window = val::global("window");
        std::string query = decode_request(window);
        return query.c_str();
    }
}

要编译,我使用以下命令:

emcc -o module.js module_2.cpp -s EXPORTED_RUNTIME_METHODS="['ccall']"  -lembind

这就是结果:

module_2.cpp:24:16: warning: address of stack memory associated with local variable 'query' returned [-Wreturn-stack-address]
   24 |         return query.c_str();
      |                ^~~~~
1 warning generated.
cache:INFO: generating system asset: symbol_lists/83809947191162c2d512457e4d02c5266930142b.json... (this will be cached in "/Users/myuser/Documents/Emscripten/emsdk/upstream/emscripten/cache/symbol_lists/83809947191162c2d512457e4d02c5266930142b.json" for subsequent builds)
cache:INFO:  - ok

这是我的 HTML 代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebAssembly Example</title>
</head>
<body>
    <h1>WebAssembly Example</h1>
    <p id="result">Result: </p>

    <button onclick="run()">Trigger</button>

    <script>
        function run() {
            WebAssembly.instantiateStreaming(
                fetch("wrapping.wasm"), {}
            ).then(result => {
                if (!result || !result.instance || !result.instance.exports) {
                    console.error("Failed to instantiate WebAssembly module.");
                    return;
                }

                var sum = result.instance.exports.myFunction();
                console.log("Result:", sum);

                document.getElementById("result").textContent = "Result: " + sum;
            }).catch(error => {
                console.error("Error loading WebAssembly module:", error);
            });
        }
    </script>
</body>
</html>

不幸的是,当我单击按钮时,我在控制台中看到此错误:

Error loading WebAssembly module: TypeError: WebAssembly.instantiate(): Import #0 module="env": module is not an object or function
(anonymous) @ (index):32
Promise.catch (async)
run @ (index):31
onclick @ (index):12

有什么建议吗?

javascript html c++ webassembly
1个回答
0
投票

通常使用 emscripten,编译器会生成加载 wasm 模块的代码(即

-o wrapping.js
)。然后,您将该
.js
文件加载到您的 html 中,它会负责加载 wasm 文件。

您可以使用

-o wrapping.wasm
直接输出 wasm 文件,但随后您需要自己实现所有 JS 支持代码。当使用 embind 时,这尤其困难,因为它依赖于大量生成 JS 支持代码。

有关独立 wasm 模式的更多信息,请参阅 https://v8.dev/blog/emscripten-standalone-wasm。总之,在这种模式下使用embind不太可行。

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