I was playing with WebAssembly and so far and I was able to manage emscripten compile my test C++ project to wasm file em++ provides me 2 files i.e.
mainTest.js mainTest.wasm
When I load mainTest.js in my html page then I get a JavaScript object called "Module".
I did found how to call C++/wasm methods from javascript i.e. something like:
var myTestInteger = Module._callMyTestMethod();
and read strings from the Module.wasmMemory.buffer , but I do NOT understand how to call JavaScript from C++ code.
i.e. I would like to be able to do something like that:
#ifdef __cplusplus
extern "C" {
#endif
extern void testExternJSMethod();
int main()
{
cout << " Hello From my Test1 !" << endl;
testExternJSMethod();
return 0;
}
int EMSCRIPTEN_KEEPALIVE callMyTestMethod(){
return 26;
}
#ifdef __cplusplus
}
#endif
and the my js method testExternMethod that I am loading in another js file called utils.js
function testExternMethod() {
console.log("Hello from testExternMethod!" + )
}
Here I would like to call the JavaScript testExternJSMethod from C++.
When I run the page in Firefox get "-1" in the debugger console.
So what I am missing in this case? Unfortunately The Mozilla documentation is giving only examples in those S-expressions instead of C++.
What am I missing in example? In C++ I have defined the method with the extern keyword i.e.
extern void testExternJSMethod();
but I get the feeling that that is not all I have to do.
I believe that I should somehow link that JavaScript method to the Module somehow but I do not know how.
Module.asm gives me the exports. Which method call should give me the imports? since I believe that this _testExternJSMethod()
should be in some imports method I can not figure out how to get to it.
I'm not exactly sure of your use case, but you are missing important steps to be able to use your function testExternalJSMethod
. You have two options here:
1 - Define your function in c/c++ .
extern void testExternalJSMethod();
2 - Create a file called myLibrary.js
3 - The JS function needs to be added to the LibraryManager
in your library file with the following code:
function makeAlert(text) {
alert(text);
}
if (typeof mergeInto !== 'undefined') mergeInto(LibraryManager.library, {
testExternalJSMethod: function() {
makeAlert("Hello world");
}
});
4 - If testExternalJSMethod
depends on anything outside of its own scope (for example, makeAlert
above), make sure to include the script in your html page
<script async type="text/javascript" src="myLibrary.js"></script>
5 - Add option --js-library
to your emcc command, and immediately after the relative path to myLibrary.js
emcc ... --js-library myLibrary.js
1 - Define your javascript function type in c/c++
typedef void testExternalJSMethod()
2 - Wherever you want this function to be used, accept an int param which will be the function pointer, and cast the pointer to your function
void passFnPointer(int ptr) {
((testExternalJSMethod*)ptr)();
}
3 - Use emscripten's addFunction()
and store its returned value (the pointer in c/c++)
var fnPtr = Module.addFunction(function () {
alert("You called testExternalJSMethod");
});
4 - Use the stored pointer value from step 3 to pass to our function passFnPointer
var passFnPointer = Module.cwrap('passFnPointer', 'undefined', ['number']);
passFnPointer(fnPtr);
5 - Add option -s RESERVED_FUNCTION_POINTERS
to your emcc command
emcc ... -s RESERVED_FUNCTION_POINTERS=10