Reputation: 567
I'm trying to do some library testing using emscripten and c++. I need to make some JavaScript variables persist between c++ calls, but I haven't been able to figure out how to do it.
I figure it's either something simple that I'm missing, or it just isn't possible. This is a standalone program with nothing else running. The following is a minimal example:
#include <emscripten.h>
int main() {
//this works and prints 1
EM_ASM(
var x = 1;
console.log(x);
);
//this throws an error 'x is not defined'
EM_ASM(
console.log(x);
);
return 0;
}
I compile and run the code using the following commands:
emcc main.cpp
node a.out.js
The output is correct for the first call, but the second call throws a not defined error. I need some way to keep this variable in scope between calls so I can use it.
Any help? Thanks.
Upvotes: 2
Views: 1484
Reputation: 3875
You could remove the var
before declaring x
:
#include <emscripten.h>
int main() {
EM_ASM(
x = 1;
console.log(x);
);
EM_ASM(
console.log(x);
);
return 0;
}
That seems to work with emcc v1.35
[edit]
Please see the explanation and much better answer of Clint
Upvotes: 2
Reputation: 2793
While the accepted answer will work, you open yourself up to some difficult to track bugs. Using x = 0
could potentially overwrite any other x
variables in the scope chain.
A better solution would be to use getter/setter functions:
cpp:
EM_ASM(
var x = 1;
setX(x);
);
EM_ASM(
var x = getX();
);
js:
var x = 0;
function getX() {
return x;
}
function setX(newX) {
x = newX;
}
Another solution would be to store the value in C++ by returning and inserting it into JS by using EM_ASM_INT
and EM_ASM_
. EM_ASM_INT
returns the return value of the javascript to cpp, while EM_ASM_
allows you to insert arguments into the javascript using $0
, $1
, $2
etc.
int cppX = 0;
int main() {
int x = EM_ASM_INT({
var x = 1;
console.log(x);
return x;
});
cppX = x;
EM_ASM_({
var x = $0;
console.log(x);
}, cppX);
return 0;
}
Upvotes: 3