Calling C++ From Javascript in Web-Apps via Webassembly

Introduction

For some complex processing in web-apps, you can code with other strict languages (e.g. Rust, C++, Go) instead of troublesome Javascript.

The current note is for C++ wasm.
The framework is as follows.

Installation

Reference: https://emscripten.org/docs/getting_started/downloads.html

1
2
3
4
5
6
7
8
9
10
11
12
13
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
# optional: check available packages
./emsdk list
# install and activate target package
./emsdk install latest
./emsdk activate latest
# add path temporarily
source ./emsdk_env.sh
# add path permanently
echo $'\nsource' `pwd`"/emsdk_env.sh > /dev/null" >> ~/.profile
# check if emcc can be used
emcc --version

TIPS: If you get any error when launching emcc even if you are succeeded in the installation (e.g. “ImportError: /usr/lib/python2.7/_ctypes.so: undefined symbol: PyUnicodeUCS2_FromUnicode”), please reinstall python. Simple reinstallation may not work. You may install it locally and replace the existing one.

Quickstart

Reference:

Processing:

  • Prepare a C++ code (e.g. main.cpp), and a html code (e.g. main.html) which includes main.js
  • Compile the C++ code
    1
    emcc -std=c++20 -o main.js main.cpp -O3 -s EXTRA_EXPORTED_RUNTIME_METHODS="['ccall']" -s LINKABLE=1 -s EXPORT_ALL=1
  • Now “main.js” and “main.wasm” must be generated.
  • Open main.html through http/https, localhost, or VSCode+LiveServer.
  • Done.

Sample Code

Reference:

This is a sample html code.
This is a sample c++ code.
A corresponded .wasm and .js file is also uploaded.

  • Section1 is to increment/decrement 1 to each 32-bit signed integer.
  • Section2 is to sort each big integer.
  • Section3 is to do both increment and sort (implemented by C struct, which is a good example of pointer accessing).

Currently Emscripten only supports types of “number” (32-bit and also pointer), “string”, “array” (8-bit), and “boolean”.