无法在 Vue 中加载 Emscripten 编译的 C++
Posted
技术标签:
【中文标题】无法在 Vue 中加载 Emscripten 编译的 C++【英文标题】:Failing to load Emscripten-compiled C++ in Vue 【发布时间】:2020-06-08 07:24:30 【问题描述】:澄清一下,我不是 C++ 专家
我有这个 C++ 代码:
#include <emscripten.h>
#include <string>
EMSCRIPTEN_KEEPALIVE
std::string test(std::string parameter)
return parameter;
int main(int argc, char** argv)
return 0;
我使用以下方法编译它:
cmake.exe --build cmake-build-emscripten --target data_converter -s EXPORTED_RUNTIME_METHODS=[cwrap] -s EXPORTED_FUNCTIONS=[_test] -s EXPORT_ES6=1 -s MODULARIZE=1 -s USE_ES6_IMPORT_META=1
请注意,我的 IDE 是 CLion,其中我的 CMake 配置是: 环境:
CC=C:\repositories\c++\data-converter\emsdk\upstream\emscripten\emcc.bat;CXX=C:\repositories\c++\data-converter\emsdk\upstream\emscripten\em++.bat;AR=C:\repositories\c++\data-converter\emsdk\upstream\emscripten\emar.bat;LD=C:\repositories\c++\data-converter\emsdk\upstream\emscripten\emcc.bat;NM=C:\repositories\c++\data-converter\emsdk\upstream\bin\llvm-nm.exe;LDSHARED=C:\repositories\c++\data-converter\emsdk\upstream\emscripten\emcc.bat;RANLIN=C:\repositories\c++\data-converter\emsdk\upstream\emscripten\emranlib.bat;EMMAKEN_COMPILER=C:\repositories\c++\data-converter\emsdk\upstream\bin\clang++.exe;EMSCRIPTEN_TOOLS=C:\repositories\c++\data-converter\emsdk\upstream\emscripten\tools;HOST_CC=C:\repositories\c++\data-converter\emsdk\upstream\bin\clang.exe;HOST_CXX=C:\repositories\c++\data-converter\emsdk\upstream\bin\clang++.exe;HOST_CFLAGS=-W;HOST_CXXFLAGS=-W;EMSCRIPTEN=C:\repositories\c++\data-converter\emsdk\upstream\emscripten
构建选项:
-s EXPORTED_RUNTIME_METHODS=["cwrap"] -s EXPORTED_FUNCTIONS=["_test"] -s EXPORT_ES6=1 -s MODULARIZE=1 -s USE_ES6_IMPORT_META=1
项目结构:
<Vue root>
└ src
└ data
└ wasm
└ data_converter.js
└ data_converter.wasm
然后,我将data_converter.js
和data_converter.wasm
移动到<Vue root>\src\data\wasm
我的 Vue 代码有:
<script>
import Module from "./data/wasm/data_converter";
export default
created()
const test = Module().cwrap("test", "string", ["string"]);
console.log(test("Hello world"));
;
</script>
当我尝试加载组件时:
Uncaught (in promise) RuntimeError: abort(CompileError: WebAssembly.instantiate(): expected magic word 00 61 73 6d, found 3c 21 44 4f @+0). Build with -s ASSERTIONS=1 for more info.
at abort (webpack-internal:///./src/data/wasm/data_converter.js:875:9)
at eval (webpack-internal:///./src/data/wasm/data_converter.js:959:7)
[Vue warn]: Error in created hook (Promise/async): "TypeError: _data_wasm_data_converter__WEBPACK_IMPORTED_MODULE_48___default(...) is not a function"
found in
---> <App> at src/App.vue
<Root>
尝试 #2 失败
由于我使用的是Webpack,所以我安装了wasm-loader,我的vue.config.js
大致如下:
module.exports =
// ...
configureWebpack:
module:
rules: [
test: /\.wasm$/,
loaders: ["wasm-loader"]
]
那么,在组件中:
import Module from "./data/wasm/data_converter";
export default
// ...
async created()
const instance = await Module();
const test = instance.exports._test;
console.log(test("Hello world"));
;
错误与上述相同。
【问题讨论】:
我认为这两个answers 都会有所帮助。根据docs,第二个答案中唯一可能出错的是,公开免费功能的选项似乎是EXPORTED_RUNTIME_METHODS
。
【参考方案1】:
3c 21 44 4f
是 <!DO
,或 html 文档的开头。您确定导入在编译时已解决,还是在运行时提取有效?
检查网络检查器以查看获取 WASM 模块的结果。
【讨论】:
在实际代码中,文件名为data_converter.wasm
。 Here is a screenshot. 现在我看到请求 URL 是 /js/data_converter.wasm
- 这是因为 vue-cli-service
正在使用 Webpack 捆绑代码,这导致创建了一个 js/
目录,.wasm
正在被移动到该目录。
我正在使用wasm-loader。现在,每当我尝试导入data_converter
(导致data_converter.js
)时,我都会在第一篇文章中收到错误消息。否则,如果我尝试导入 data_converter.wasm
、this is the error。
您的第一条评论隐藏了最重要的部分:响应标头!我猜 Content-Type 是 text/html
而不是 WASM。可能是一些错误页面。如果您直接获取该网址,您会得到什么?
至于您的第二次尝试:.wasm
文件的前几个字节是什么?应该是00 61 73 6d
。
确实是以上是关于无法在 Vue 中加载 Emscripten 编译的 C++的主要内容,如果未能解决你的问题,请参考以下文章
使用 Typescript 在 vue.js 中加载 JSON 文件
无法在 Visual C++ 中加载 SQL 驱动程序(但在 QtCreator 中加载)