首页 > 解决方案 > 无法在 Vue 中加载 Emscripten 编译的 C++

问题描述

需要明确的是,我不是 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.jsanddata_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"));
  }
};

错误与上述错误相同。

标签: webpackwebassemblyemscripten

解决方案


3c 21 44 4fis <!DO,或 HTML 文档的开头。您确定导入是在编译时解决的,还是在运行时提取有效?

检查网络检查器以查看获取 WASM 模块的结果。


推荐阅读