Suppose I have function x
in C++ defined as:
extern "C" void x();
and I implement it in JS in global context
function _x() { console.log('x called'); }
_x
is defined in asm compiled js file, which is getting invoked and not my implementation. What am I doing wrong?
I'm getting this warning while linking:
warning: unresolved symbol: x
Here is the stacktrace:
Uncaught abort() at Error
at jsStackTrace (http://localhost/module.js:978:13)
at stackTrace (http://localhost/module.js:995:22)
at abort (http://localhost/module.js:71106:25)
at _x (http://localhost/module.js:5829:46)
at Array._x__wrapper (http://localhost/module.js:68595:41)
at Object.dynCall_vi (http://localhost/module.js:68442:36)
at invoke_vi (http://localhost/module.js:7017:25)
at _LoadFile (http://localhost/module.js:7573:6)
at asm._LoadFile (http://localhost/module.js:69219:25)
at eval (eval at cwrap (http://localhost/module.js:554:17), <anonymous>:6:26)
As described at Implement a C API in Javascript, you define a library by having a Javascript file that calls mergeInto
to merge an object with your Javascript functions into LibraryManager.library
. You then compile with the --js-library
option to pass in the location of your library.
For example, you can have Javascript file with your library of a single function
// In library.js
mergeInto(LibraryManager.library, {
x: function() {
alert('hi');
},
});
a main C++ file that calls this function
// in librarytest.cc
extern "C" void x();
int main()
{
x();
return 0;
}
and compile to HTML and Javascript with
em++ librarytest.cc --js-library library.js -o librarytest.html
then you load librarytest.html
in a browser, it will show an alert box with hi
.
If you want to pass a string from C++ to Javascript, you don't have to go the route of Implement a C API in Javascript. Instead, you can use the EM_ASM* macros to directly inline the Javascript. This can then call out to Javascript functions you have defined, and pass their values.
Also, to pass a string, you need to make sure you pass a C-style string, and then use the Emscripten-supplied Pointer_stringify
Javascript function on the result:
#include <string>
#include <emscripten.h>
int main()
{
std::string myString("This is a string in C++");
EM_ASM_ARGS({
console.log(Pointer_stringify($0));
}, myString.c_str());
return 0;
}