Arbeit mit WebAssembly und JavaScript: von A bis Z in Node.js

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 seine Rolle in Node.js

\n\n

WebAssembly (WASM) ist ein binäres Low-Level-Anweisungsformat, das in einer virtuellen Maschine mit nahezu nativer Leistung ausgeführt wird. Im Node.js-Ökosystem eröffnet WebAssembly neue Horizonte: Es ermöglicht die Ausführung von Code, der in C, C++, Rust oder Go geschrieben wurde, direkt in der Serverumgebung. Dies ist besonders relevant für Aufgaben, die eine hohe Leistung erfordern: Bildverarbeitung, Kryptographie, Datenparsing, Arbeit mit großen Zahlenarrays.

\n\n

In diesem Artikel behandeln wir den gesamten Arbeitszyklus mit WebAssembly in Node.js: von der Kompilierung des Quellcodes bis zur Integration des fertigen Moduls in eine JavaScript-Anwendung.

\n\n

Grundlegende Konzepte und Vorbereitung der Umgebung

\n\n

Was Sie vor dem Start wissen sollten

\n

Ein WebAssembly-Modul ist eine Binärdatei mit der Erweiterung .wasm. Es hat keinen direkten Zugriff auf das DOM oder das Dateisystem – die gesamte Interaktion erfolgt über "importierte Funktionen", die Sie aus JavaScript übergeben. In Node.js wird diese Einschränkung durch spezielle Wrapper aufgehoben.

\n\n

Installation der Werkzeuge

\n

Zum Kompilieren von Code in WASM benötigen wir das Emscripten SDK. Installation unter Linux/macOS:

\n
git clone https://github.com/emscripten-core/emsdk.git\ncd emsdk\n./emsdk install latest\n./emsdk activate latest\nsource ./emsdk_env.sh
\n\n

Für Rust-Projekte verwenden Sie wasm-pack:

\n
npm install -g wasm-pack
\n\n

Erstellung und Kompilierung des ersten WASM-Moduls

\n\n

Beispiel in C – Additionsfunktion

\n

Erstellen wir eine einfache Funktion in C, die zwei Zahlen addiert:

\n
// math.c\n#include <emscripten.h>\n\nEMSCRIPTEN_KEEPALIVE\nint add(int a, int b) {\n    return a + b;\n}\n\nEMSCRIPTEN_KEEPALIVE\nint multiply(int a, int b) {\n    return a * b;\n}
\n\n

Kompilieren in WASM mit Emscripten:

\n
emcc math.c -o math.js -s EXPORTED_FUNCTIONS="['_add', '_multiply']" -s WASM=1 -s MODULARIZE=1 -s EXPORT_NAME="createMathModule"
\n\n

Als Ergebnis erhalten wir zwei Dateien: math.wasm und math.js – einen Wrapper zum Laden.

\n\n

Laden des Moduls in Node.js

\n

Jetzt verwenden wir das Modul in JavaScript:

\n
// index.js\nconst createMathModule = require('./math.js');\n\ncreateMathModule().then(module => {\n    const add = module._add;\n    const multiply = module._multiply;\n\n    console.log('5 + 3 =', add(5, 3));        // 8\n    console.log('4 * 7 =', multiply(4, 7));  // 28\n});
\n\n

Ausführen:

\n
node index.js
\n\n

Arbeit mit Speicher und komplexen Datentypen

\n\n

Übergabe von Strings und Arrays

\n

WASM arbeitet nur mit Zahlen. Zum Übergeben von Strings oder Arrays muss Speicher im linearen Speicher des Moduls reserviert werden. Betrachten wir ein Beispiel in C, das einen String entgegennimmt und dessen Länge zurückgibt:

\n
// string_ops.c\n#include <string.h>\n#include <emscripten.h>\n\nEMSCRIPTEN_KEEPALIVE\nint string_length(char* str) {\n    return strlen(str);\n}\n\nEMSCRIPTEN_KEEPALIVE\nvoid to_upper(char* str) {\n    for (int i = 0; str[i]; i++) {\n        if (str[i] >= 'a' && str[i] <= 'z') {\n            str[i] -= 32;\n        }\n    }\n}
\n\n

Kompilieren:

\n
emcc string_ops.c -o string_ops.js -s EXPORTED_FUNCTIONS="['_string_length', '_to_upper']" -s WASM=1 -s MODULARIZE=1 -s EXPORT_NAME="createStringModule"
\n\n

JavaScript-Code für die Arbeit mit dem Speicher:

\n
const createStringModule = require('./string_ops.js');\n\ncreateStringModule().then(module => {\n    const { _string_length, _to_upper, heap } = module;\n    \n    // Speicher für den String reservieren\n    const input = "hello world";\n    const ptr = module._malloc(input.length + 1);\n    \n    // String in den WASM-Speicher kopieren\n    for (let i = 0; i < input.length; i++) {\n        heap[i + ptr] = input.charCodeAt(i);\n    }\n    heap[ptr + input.len                

Blogs

Buchempfehlungen