Arbeiten mit WebAssembly und C++: Von A bis Z

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einführung in WebAssembly und C++

\n\n

Die 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\n

In 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\n

1. Werkzeuge und Umgebungseinrichtung

\n\n

Das 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\n

Installation von Emscripten

\n

Die empfohlene Installationsmethode ist über den Paketmanager emsdk:

\n\n
# 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\n

Nach der Installation stehen Ihnen die Befehle emcc (Compiler) und em++ (C++-Compiler) zur Verfügung, die Wrapper um Clang sind.

\n\n

2. Kompilierung von C++ in WebAssembly

\n\n

Betrachten wir ein einfaches Beispiel. Erstellen wir eine Datei hello.cpp:

\n\n
#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\n

Ein wichtiges Element ist das Makro EMSCRIPTEN_KEEPALIVE. Es verhindert, dass die Funktion vom Optimierer entfernt wird, und macht sie exportierbar.

\n\n

Kompilieren wir unseren Code:

\n\n
em++ hello.cpp -o hello.html -s WASM=1 -s EXPORTED_FUNCTIONS='["_add"]' -O3
\n\n

Erklä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
\n\n

Als Ergebnis erhalten wir drei Dateien: hello.html, hello.js (Glue-Code) und hello.wasm.

\n\n

3. Interaktion mit JavaScript

\n\n

Nach 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\n

Wichtige 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._malloc und Zeiger verwendet.
  • \n
\n\n

Übergabe von Strings

\n

Beispiel 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\n

In JavaS

Blogs

Buchempfehlungen