Lucas
Lucas

Reputation: 567

How can I use C++ to assign variables in JavaScript using Emscripten and keep them in scope?

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

Answers (2)

KompjoeFriek
KompjoeFriek

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

Clint
Clint

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

Related Questions