我是 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
有什么建议吗?
通常使用 emscripten,编译器会生成加载 wasm 模块的代码(即
-o wrapping.js
)。然后,您将该 .js
文件加载到您的 html 中,它会负责加载 wasm 文件。
您可以使用
-o wrapping.wasm
直接输出 wasm 文件,但随后您需要自己实现所有 JS 支持代码。当使用 embind 时,这尤其困难,因为它依赖于大量生成 JS 支持代码。
有关独立 wasm 模式的更多信息,请参阅 https://v8.dev/blog/emscripten-standalone-wasm。总之,在这种模式下使用embind不太可行。