Learning Emscripten: Compile C/C++ to JavaScript

What is Emscripten

WebAssembly-supported web browsers:

  • Firefox 52+
  • Chrome 57+
  • Latest Opera
  • Firefox 47+: enable the options.wasm flag in about:config
  • Chrome 51+: enable experimental WebAssembly flag in chrome://flags

Download and Installation

Getting Started

#include <stdio.h>int main() {printf("hello\n");return 0;}
emcc hello.c
node a.out.js
emcc hello.c -o hello.html
emcc hello.c -s WASM=1 -o hello2.html
emrun hello2.html

Call C/C++ APIs

Export functions by command line

#include <stdio.h>#include <emscripten.h>char* world() {return "world";}int main() {printf("hello\n");return 0;}
emcc -s EXPORTED_FUNCTIONS="['_world']" hello.c -o hello.html
<button onclick="native()">click</button><script type='text/javascript'>function native() {var content = Module.ccall('world', 'string');alert(content);}</script>
var hello_module = require('./hello.js');console.log(hello_module.ccall('world', 'string'));

Define the function with EMSCRIPTEN_KEEPALIVE

char* EMSCRIPTEN_KEEPALIVE world() {return "world";}
emcc hello.c -o hello.html
int main() {printf("hello\n");emscripten_exit_with_live_runtime();return 0;}
emcc hello.c -o hello.html -s NO_EXIT_RUNTIME=1

Preload resource files

emcc hello.c -o hello.html --preload-file ./asset
void getLicense() {char license[256];int index = 0;FILE *file = fopen("./asset/license.txt", "r");if (!file) {printf("cannot open file\n");return;}while (!feof(file)) {char c = fgetc(file);if (c != EOF) {license[index++] = c;}}fclose (file);printf("%s\n", license);}

Module initialization status

setStatus: function(text) {if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' };if (text === Module.setStatus.text) return;var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);var now = Date.now();if (m && now - Date.now() < 30) return; // if this is a progress update, skip it if too soonif (m) {text = m[1];progressElement.value = parseInt(m[2])*100;progressElement.max = parseInt(m[4])*100;progressElement.hidden = false;spinnerElement.hidden = false;} else {progressElement.value = null;progressElement.max = null;progressElement.hidden = true;if (!text) spinnerElement.style.display = 'none';}statusElement.innerHTML = text;}
int main() {EM_ASM(onLoaded());return 0;}
<script>// called from main()function onLoaded() {alert('Module is loaded');}</script>
<script>// called when the runtime is readyvar Module = {onRuntimeInitialized: function () {alert('onRuntimeInitialized');}};</script>
<!doctype html><html><head></head><body><h1>Custom Page</h1><button onclick="native()">click</button><script>// called when the runtime is readyvar Module = {onRuntimeInitialized: function () {alert('onRuntimeInitialized');}};// called from main()function onLoaded() {alert('Module is loaded');}function native() {var content = Module.ccall('world', 'string');alert(content);}</script><script async type="text/javascript" src="hello.js"></script></body></html>

Resources

Source Code

--

--

--

Manager of Dynamsoft Open Source Projects | Tech Lover

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Watching tests — Mocha & Babel & React

Authentication with NodeJS/ExpressJS The simple way

Why we need Redux?

JAVASCRIPT CLOSURES SIMPLIFIED

Explaining Asynchronous Javascript

Holochain-Rust 0.0.2 Released! Time to #BUIDL!

Introduction To Shadow DOM In JavaScript

Laptop-Dom Elements.

Modules and Code Splitting in Webpack 5

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Xiao Ling

Xiao Ling

Manager of Dynamsoft Open Source Projects | Tech Lover

More from Medium

React JS vs Angular- Know ins and Outs

How to Use the Counting Sort Algorithm in JavaScript

Basics of JavaScript and Version Controlling

Intro to Linked Lists — Singly (JavaScript)