问题
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.
回答1:
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:
Option 1 - Library
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
Option 2 - Passing Pointers
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
回答2:
Have you tried looking at the Emscripten documentation? It has a whole section on interacting with code that details how to expose C / C++ functions to JavaScript and call JavaScript functions from C / C++.
Emscripten provides two main approaches for calling JavaScript from C/C++: running the script using emscripten_run_script() or writing “inline JavaScript”.
It is worth noting that the Mozilla documentation details plain WebAssembly, whereas Emscripten adds a lot more framework and tooling around WebAssembly in order to make it easier to port large C / C++ codebases.
来源:https://stackoverflow.com/questions/47248045/webassembly-calling-javascript-methods-from-wasm-i-e-within-c-code