Search code examples
javascriptc++cross-platformemcc

Is there a way to use C++ in JavaScript?


From this, I found out that JavaScript is written in C++. I also have found out/deduced that a majority of JavaScript is C++ (e.g. Math.atan+"" and Math.atan.toString() yielding "function atan() { [native code] }"). The [native code I assume to be C++, else what would be the point of 'hiding' it?

My question is there a way to utilize C++ in JavaScript? To use it in a function or in the JavaScript platform?


Solution

  • The emscripten project allows you to to generate Javascript from C and C++:

    Emscripten is an LLVM-to-JavaScript compiler. It takes LLVM bitcode - which can be generated from C/C++, using llvm-gcc (DragonEgg) or clang, or any other language that can be converted into LLVM - and compiles that into JavaScript, which can be run on the web (or anywhere else JavaScript can run).

    and through methods like ccall and cwrap you can call C functions:

    Using the example from the site, this C++ code which used extern "C" to prevent name mangling:

    #include <math.h>
    
    extern "C" {
    
    int int_sqrt(int x) {
      return sqrt(x);
    }
    
    }
    

    can be compiled like so:

    ./emcc tests/hello_function.cpp -o function.html -s EXPORTED_FUNCTIONS="['_int_sqrt']"
    

    and used in Javascript:

    int_sqrt = Module.cwrap('int_sqrt', 'number', ['number'])
    int_sqrt(12)
    int_sqrt(28)
    

    embind can be used for C++ functions and classes. The quick example from the site is as follows:

    // quick_example.cpp
    #include <emscripten/bind.h>
    
    using namespace emscripten;
    
    float lerp(float a, float b, float t) {
        return (1 - t) * a + t * b;
    }
    
    EMSCRIPTEN_BINDINGS(my_module) {
        function("lerp", &lerp);
    }
    

    and compile:

    emcc --bind -o quick_example.js quick_example.cpp
    

    and use in Javascript:

    <!doctype html>
    <html>
      <script src="quick_example.js"></script>
      <script>
        console.log('lerp result: ' + Module.lerp(1, 2, 0.5));
      </script>
    </html>