Failing to load Emscripten-compiled C++ in Vue

Viewed 397

Just to be clear, I'm not a C++ expert

I have this C++ code:

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

EMSCRIPTEN_KEEPALIVE
std::string test(std::string parameter) {
    return parameter;
}

int main(int argc, char** argv) {
    return 0;
}

I compiled it using:

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

Note that my IDE is CLion, in which my CMake configurations are:
Environment:

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

Build options:

-s EXPORTED_RUNTIME_METHODS=["cwrap"] -s EXPORTED_FUNCTIONS=["_test"] -s EXPORT_ES6=1 -s MODULARIZE=1 -s USE_ES6_IMPORT_META=1

Project structure:

<Vue root>
  └ src
     └ data
         └ wasm
             └ data_converter.js
             └ data_converter.wasm

Then, I moved the data_converter.js and data_converter.wasm to <Vue root>\src\data\wasm

My Vue code has:

<script>
import Module from "./data/wasm/data_converter";

export default {
  created() {
    const test = Module().cwrap("test", "string", ["string"]);
    console.log(test("Hello world"));
  }
};
</script>

When I try to load the component:

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>

Failed attempt #2

Since I'm using Webpack, I installed wasm-loader, my vue.config.js roughly looks like:

module.exports = {
  // ...
  configureWebpack: {
    module: {
      rules: [
        {
          test: /\.wasm$/,
          loaders: ["wasm-loader"]
        }
      ]
    }
  }
}

Then, in the component:

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"));
  }
};

The error is the same as the aforementioned one.

1 Answers

3c 21 44 4f is <!DO, or the start of a HTML document. Are you sure the import is resolved at compile time or that the fetch at runtime works?

Check with the network inspector to see the result of fetching the WASM module.

Related