Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
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
-Ozflag for size optimization:emcc code.cpp -o output.js -Oz -s WASM=1Function Inlining Enable aggressive inlining with
-s AGGRESSIVE_VARIABLE_ELIMINATION=1Dead 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+
