How do I link a C++ program with an HTML page?

WebAssembly (WASM) is a binary instruction format that enables high-performance languages like C++ to run in web browsers. It allows developers to integrate C++ functionality directly into web applications by compiling C++ code to WebAssembly and calling it from JavaScript within HTML pages.

Prerequisites

Before starting, ensure you have the following tools installed

  • C++ Compiler GCC (GNU Compiler Collection) or Visual Studio with C++ support.

  • Emscripten SDK A toolchain that compiles C++ to WebAssembly. Download from the official website at https://emscripten.org.

Step 1: Install Emscripten SDK

Download and install the Emscripten SDK using the following commands

git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.sh

Step 2: Write the C++ Code

Create a simple C++ program with functions you want to call from JavaScript. Note that WebAssembly runs in a sandboxed environment, so avoid system-specific operations like file I/O or direct hardware access.

Example Basic Math Functions

Create a file called math_functions.cpp

#include <emscripten/emscripten.h>

extern "C" {
    EMSCRIPTEN_KEEPALIVE
    int factorial(int n) {
        if (n == 0 || n == 1) 
            return 1;
        else
            return n * factorial(n - 1);
    }
    
    EMSCRIPTEN_KEEPALIVE
    double power(double base, int exp) {
        double result = 1;
        for (int i = 0; i < exp; i++) {
            result *= base;
        }
        return result;
    }
}

The EMSCRIPTEN_KEEPALIVE macro ensures these functions are exported and accessible from JavaScript.

Step 3: Compile C++ to WebAssembly

Use Emscripten to compile the C++ code to WebAssembly format

emcc math_functions.cpp -o math_functions.js -s WASM=1 -s EXPORTED_RUNTIME_METHODS="['ccall','cwrap']"

This command generates two files: math_functions.js (JavaScript wrapper) and math_functions.wasm (WebAssembly binary).

Step 4: Create the HTML Page

Create an HTML page that loads the WebAssembly module and calls the C++ functions

Example

<!DOCTYPE html>
<html>
<head>
    <title>C++ WebAssembly Integration</title>
    <style>
        body { font-family: Arial, sans-serif; padding: 20px; }
        .result { background: #f0f8ff; padding: 10px; margin: 10px 0; border-radius: 5px; }
        button { padding: 8px 16px; margin: 5px; cursor: pointer; }
    </style>
</head>
<body>
    <h1>C++ WebAssembly Demo</h1>
    
    <h3>Factorial Calculator</h3>
    <input type="number" id="factInput" value="5" min="0" max="12">
    <button onclick="calculateFactorial()">Calculate Factorial</button>
    <div id="factResult" class="result"></div>
    
    <h3>Power Calculator</h3>
    <input type="number" id="baseInput" value="2" step="0.1"> ^
    <input type="number" id="expInput" value="3" min="0" max="10">
    <button onclick="calculatePower()">Calculate Power</button>
    <div id="powerResult" class="result"></div>
    
    <script src="math_functions.js"></script>
    <script>
        let moduleReady = false;
        
        Module.onRuntimeInitialized = function() {
            moduleReady = true;
            document.getElementById("factResult").textContent = "WebAssembly module loaded successfully!";
            calculateFactorial(); // Show initial result
        };
        
        function calculateFactorial() {
            if (!moduleReady) return;
            const num = parseInt(document.getElementById("factInput").value);
            const result = Module._factorial(num);
            document.getElementById("factResult").textContent = `Factorial of ${num} = ${result}`;
        }
        
        function calculatePower() {
            if (!moduleReady) return;
            const base = parseFloat(document.getElementById("baseInput").value);
            const exp = parseInt(document.getElementById("expInput").value);
            const result = Module._power(base, exp);
            document.getElementById("powerResult").textContent = `${base}^${exp} = ${result}`;
        }
    </script>
</body>
</html>

The output displays interactive calculators that use C++ functions compiled to WebAssembly

C++ WebAssembly Demo

Factorial Calculator
[5] [Calculate Factorial]
Factorial of 5 = 120

Power Calculator  
[2] ^ [3] [Calculate Power]
2^3 = 8

Step 5: Test the Application

To test the application, you need to serve it from a web server due to CORS restrictions. You can use a simple HTTP server

# Using Python 3
python -m http.server 8000

# Using Node.js
npx http-server

Open your browser and navigate to http://localhost:8000 to see the application in action.

Advanced Integration Techniques

Using ccall and cwrap

For more complex parameter passing, use Emscripten's ccall and cwrap functions

<!DOCTYPE html>
<html>
<head>
    <title>Advanced WebAssembly Integration</title>
</head>
<body style="font-family: Arial, sans-serif; padding: 20px;">
    <h2>Advanced C++ Integration</h2>
    <button onclick="testCCall()">Test ccall</button>
    <button onclick="testCWrap()">Test cwrap</button>
    <div id="output" style="background: #f5f5f5; padding: 10px; margin-top: 10px;"></div>
    
    <script src="math_functions.js"></script>
    <script>
        Module.onRuntimeInitialized = function() {
            // Wrap C++ function for easier calling
            window.factorialWrapper = Module.cwrap('factorial', 'number', ['number']);
            document.getElementById("output").textContent = "Module initialized!";
        };
        
        function testCCall() {
            // Direct call using ccall
            const result = Module.ccall('factorial', 'number', ['number'], [6]);
            document.getElementById("output").textContent = `ccall result: factorial(6) = ${result}`;
        }
        
        function testCWrap() {
            // Using wrapped function
            if (window.factorialWrapper) {
                const result = window.factorialWrapper(7);
                document.getElementById("output").textContent = `cwrap result: factorial(7) = ${result}`;
            }
        }
    </script>
</body>
</html>

Memory Management

When working with strings or arrays, you need to manage memory allocation between JavaScript and WebAssembly. Here's how to handle string parameters

#include <emscripten/emscripten.h>
#include <string>

extern "C" {
    EMSCRIPTEN_KEEPALIVE
    int stringLength(const char* str) {
        return strlen(str);
    }
    
    EMSCRIPTEN_KEEPALIVE
    char* reverseString(const char* str) {
        int len = strlen(str);
        char* result = (char*)malloc(len + 1);
        for (int i = 0; i < len; i++) {
            result[i] = str[len - 1 - i];
        }
        result[len] = '\0';
        return result;
    }
}

Performance Optimization

To optimize your WebAssembly module for production

  • Size Optimization Use -Oz flag for size optimization: emcc code.cpp -o output.js -Oz -s WASM=1

  • Function Inlining Enable aggressive inlining with -s AGGRESSIVE_VARIABLE_ELIMINATION=1

  • Dead Code Elimination Remove unused code with -s ELIMINATE_DUPLICATE_FUNCTIONS=1

Common Issues and Solutions

Issue Solution
Functions not accessible from JavaScript Add EMSCRIPTEN_KEEPALIVE macro and extern "C" wrapper
CORS errors when loading files Serve files from a web server, not directly from file system
Module not initialized error Wait for Module.onRuntimeInitialized before calling functions
Memory leaks with strings Manually free allocated memory using Module._free()

Browser Support

WebAssembly is supported in all modern browsers:

  • Chrome 57+

  • Firefox 52+

  • Safari 11+

  • Edge 16+

C++ to WebAssembly Integration Flow C++ Code emcc WebAssembly (.wasm) JavaScript Wrapper HTML Page ? factorial() ? power() Binary format Fast execution Module._factorial
Updated on: 2026-03-16T21:38:54+05:30

10K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements