Search code examples
javascriptc++webassemblyemscriptenembind

How to import class in WASM and use it out of onRuntimeInitialized?


I try to use embind to bind my c++ code to js. I find I can only use function and class in Module.onRuntimeInitilized. How can I use those functions and classes out of the onRuntimeInitilized as a usual object, or if I can only initilize the module once when the whole program start?

var module = require('./molcpp');


module["onRuntimeInitialized"] = () => {

    var box = new module.Box();
    box.set_lengths_and_angles(new module.Vec3(1, 2, 3), new module.Vec3(90, 90, 90));
    var mat = box.matrix;
    console.log("test");
    // return module.Box;

};

As you can see, I can only use those things in this callback function. I want use them in other class and invocked by others.


Solution

  • The simple answer is you cannot, at least not directly. The WASM API is asynchronous.

    It is meant to be used mainly by browsers which are highly asynchronous. In the browser this is not a problem.

    I guess that you want to be able to import this in your other classes.

    One solution is to export a Promise and to use await:

    const wasm = require('./molcpp');
    
    const api = new Promise((resolve) => {
      wasm['onRuntimeInitialized'] = () => {
        resolve(wasm);
      };
    };
    
    module.exports = api;
    

    Then when you import it:

    // Only ES6 supports top-level await
    import wasm from './wasm';
    
    (await wasm).wasmMethod(....);