Einführung in WebAssembly und C++
\n\nDie moderne Webentwicklung sucht ständig nach Möglichkeiten, die Leistung zu steigern. WebAssembly (Wasm) ist ein binäres Low-Level-Befehlsformat, das im Browser mit nahezu nativer Geschwindigkeit ausgeführt wird. In Kombination mit C++, einer der schnellsten und leistungsfähigsten Programmiersprachen, eröffnet Wasm neue Horizonte: von leistungsstarken Spielen und Simulationen bis hin zu komplexen Datenverarbeitungsalgorithmen direkt im Browser.
\n\nIn diesem Artikel gehen wir den Weg von den Grundlagen bis zur praktischen Anwendung: Wir erklären, wie man C++-Code in WebAssembly kompiliert, im Browser ausführt und für maximale Leistung optimiert.
\n\n1. Werkzeuge und Umgebungseinrichtung
\n\nDas wichtigste Werkzeug zum Kompilieren von C++ in WebAssembly ist der Compiler-Suite Emscripten. Er übersetzt LLVM-Bytecode in Wasm und generiert automatisch den JavaScript-Glue-Code, der zum Laden des Moduls erforderlich ist.
\n\nInstallation von Emscripten
\nDie empfohlene Installationsmethode ist über den Paketmanager emsdk:
# Repository klonen\ngit clone https://github.com/emscripten-core/emsdk.git\ncd emsdk\n\n# Neueste Version installieren und aktivieren\n./emsdk install latest\n./emsdk activate latest\n\n# Umgebungsvariablen hinzufügen (Shell-Variablen)\nsource ./emsdk_env.sh\n\nNach der Installation stehen Ihnen die Befehle emcc (Compiler) und em++ (C++-Compiler) zur Verfügung, die Wrapper um Clang sind.
2. Kompilierung von C++ in WebAssembly
\n\nBetrachten wir ein einfaches Beispiel. Erstellen wir eine Datei hello.cpp:
#include <emscripten/emscripten.h>\n\n// Funktion, die von JavaScript aus zugänglich ist\nextern "C" {\n int EMSCRIPTEN_KEEPALIVE add(int a, int b) {\n return a + b;\n }\n}\n\nEin wichtiges Element ist das Makro EMSCRIPTEN_KEEPALIVE. Es verhindert, dass die Funktion vom Optimierer entfernt wird, und macht sie exportierbar.
Kompilieren wir unseren Code:
\n\nem++ hello.cpp -o hello.html -s WASM=1 -s EXPORTED_FUNCTIONS='["_add"]' -O3\n\nErklärung der Flags:
\n- \n
-o hello.html— erstellt eine HTML-Datei mit einem Beispielaufruf. \n -s WASM=1— explizite Angabe zur Generierung von Wasm (standardmäßig aktiviert). \n -s EXPORTED_FUNCTIONS='["_add"]'— Liste der exportierten Funktionen (mit Präfix_). \n -O3— hohe Optimierungsstufe. \n
Als Ergebnis erhalten wir drei Dateien: hello.html, hello.js (Glue-Code) und hello.wasm.
3. Interaktion mit JavaScript
\n\nNach der Kompilierung können wir unsere C++-Funktion aus JavaScript aufrufen. Hier ist ein minimaler Code zum Laden des Moduls:
\n\n<!DOCTYPE html>\n<html>\n<head>\n <script>\n var Module = {};\n Module.onRuntimeInitialized = function() {\n // Die Funktion add ist jetzt verfügbar\n var result = Module._add(5, 7);\n console.log("Ergebnis: " + result); // 12\n };\n </script>\n <script src="hello.js"></script>\n</head>\n<body></body>\n</html>\n\nWichtige Punkte:
\n- \n
Module.onRuntimeInitialized— Ereignis, das nach dem Laden des Wasm-Moduls ausgelöst wird. \n - Funktionsnamen in JS erhalten das Präfix
_(z. B._add). \n - Zur Übergabe komplexer Datenstrukturen (Strings, Arrays) werden
Module._mallocund Zeiger verwendet. \n
Übergabe von Strings
\nBeispiel einer Funktion, die eine Begrüßung zurückgibt:
\n\n// C++-Code\nextern "C" {\n const char* EMSCRIPTEN_KEEPALIVE greet(const char* name) {\n static std::string msg = "Hallo, " + std::string(name) + "!";\n return msg.c_str();\n }\n}\n\nIn JavaS