1

I want to create a simple dialog in a browser that takes button click as input using WebAssembly.

I have succeeded creating an application using OpenGL, SDL2, and imGui and ported it to JavaScript using Emscripten. But I have problems passing data from the WebAssembly OpenGL application to JavaScript.

How can I pass data from C++ to Javascript to acknowledge the web page that users have done some actions (ex: Clicking "OK" button)?

I've tried to stop the Emscripten run loop using emscripten_cancel_main_loop. And the application just freezes on the web page.
I'm trying to emit events from C++ to JavaScript but couldn't figure out how it works.

1
  • can't you declare JS functions and call them? Commented Jul 18, 2022 at 13:51

2 Answers 2

3

After several attempts, I've come to an approach to dispatch CustomEvent from WebAssembly to my Web page.

The function that was used to send data looks like this:

EM_JS(void, sendData, (int data), {
    window.dispatchEvent(
        new CustomEvent("fromWASM", {
            detail: {
                data: data
            }
        })
    );
});

Then call sendData() directly on C++ code as if it was a normal C++ function.

Finally, we'll need to listen to the event on the JavaScript side with addEventListener:

window.addEventListener('fromWASM', (event) => {
    console.log(event.detail);
});

I'm also wondering can we pass messages from the web page to the OpenGL application?

Sign up to request clarification or add additional context in comments.

Comments

3

You are going about this the entirely wrong way. I simply do this in C++ to easily control my web content:

#include <../emsdk/emscripten/master/system/include/emscripten.h>


/* in your C++ code somewhere */
emscripten_run_script('alert(\"The operation is completed!\");');

emscripten_run_script will execute arbitrary Javascript code in the context of the document where the webassembly is loaded.


EDIT

If you wanted to perform the operation in reverse (calling a C++ method from the javascript context), you would want to expose the C++ method to Javascript like this:

#include <emscripten/bind.h>

int myFunction(int x) {
    // Your C++ code here
    return x * 2; // Example operation
}

EMSCRIPTEN_BINDINGS(my_module) {
    emscripten::function("myFunction", &myFunction);
}

Now in the Javascript context:

// Call the C++ function from JavaScript
const result = Module.myFunction(10);

// Decide what to do with the result
console.log(result); // Use the result in your JavaScript code

You can even pass Javascript functions as callbacks using emscripten::val and use them like any other javascript callback.

#include <emscripten.h>

void myFunctionWithCallback(int x, emscripten::val callback) {
    int result = x * 2; // Example operation
    // Convert the result to a val before passing to callback
    callback(emscripten::val(result)); }

EMSCRIPTEN_BINDINGS(my_module) {
    emscripten::function("myFunctionWithCallback", &myFunctionWithCallback); }

2 Comments

I want to wrap the C++ function in a JS function so that it can decide what to do after the user has taken action. How can I pass the result data to the Javascript calling function using emscripten_run_script?
You would have to setup a C++ binding.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.