WebAssembly - Lavorare con C++

Ciao, aspiranti programmatori! Sono entusiasta di essere il tuo guida in questo viaggio emozionante nel mondo di WebAssembly e C++. Come qualcuno che ha insegnato scienze informatiche per oltre un decennio, posso assicurarti che mentre questo argomento potrebbe sembrare inizialmente intimidatorio, lo break down in pezzi più piccoli che anche i principianti assoluti possono digerire. Allora, mettiamo le maniche su e tuffiamoci!

WebAssembly - Working with C++

Cos'è WebAssembly?

Prima di immergerci nel codice, capiamo di cosa si occupa WebAssembly. Immagina di voler parlare con qualcuno che non conosce la tua lingua. Avresti bisogno di un traduttore, vero? Beh, WebAssembly è come quel traduttore per il tuo browser web. Permette ai programmi scritti in linguaggi come C++ di funzionare nei browser a velocità quasi nativa. Cool, vero?

Perché C++ con WebAssembly?

Ti potresti chiedere, "Perché C++?" Beh, C++ è come il coltello svizzero dei linguaggi di programmazione - è potente, flessibile e presente da anni. Combinato con WebAssembly, ci permette di portare applicazioni ad alte prestazioni sul web. È come sovralimentare il tuo sito web!

Configurazione del Nostro Ambiente

Prima di scrivere la nostra prima riga di codice, dobbiamo configurare il nostro spazio di lavoro. Non preoccuparti, ti guiderò passo dopo passo:

  1. Installa Emscripten: Questo è il nostro bastone magico che trasforma C++ in WebAssembly.
  2. Configura un editor di testo: Ti consiglio Visual Studio Code, ma ogni editor di testo andrà bene.
  3. Apri un terminale: Lo useremo per compilare il nostro codice.

Il Nostro Primo Programma WebAssembly

Iniziamo con un semplice programma "Ciao, Mondo!". Ecco il codice:

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

extern "C" {
EMSCRIPTEN_KEEPALIVE
void sayHello() {
printf("Ciao, Mondo WebAssembly!\n");
}
}

Ora, analizziamo questo:

  • #include <emscripten/emscripten.h>: Questa riga include il file header di Emscripten, dandoci accesso a funzioni correlate a WebAssembly.
  • extern "C": Questo dice al compilatore di usare la denominazione in stile C per le nostre funzioni.
  • EMSCRIPTEN_KEEPALIVE: Questo è come mettere un cartello "Non Cancellare" sulla nostra funzione, assicurandosi che sia disponibile per JavaScript.
  • void sayHello(): Questa è la nostra funzione che stampa il saluto.

Compilazione del Nostro Codice

È giunto il momento di scoccare il nostro incantesimo! Nel tuo terminale, esegui:

emcc hello.cpp -o hello.html -s NO_EXIT_RUNTIME=1 -s "EXPORTED_RUNTIME_METHODS=['ccall']"

Questo comando potrebbe sembrare un incantesimo da Harry Potter, ma lasciami spiegare:

  • emcc: Questo è il nostro compilatore.
  • hello.cpp: Il nostro file sorgente.
  • -o hello.html: Questo crea un file HTML che possiamo aprire nel browser.
  • Il resto sono flag speciali per fare in modo che il nostro WebAssembly funzioni bene con JavaScript.

Esecuzione del Nostro WebAssembly

Apri il file generato hello.html nel tuo browser, apri la console e digita:

Module.ccall('sayHello', null, null, null);

Se vedi "Ciao, Mondo WebAssembly!" nella console, congratulazioni! Hai appena eseguito C++ nel tuo browser!

Un Esempio Più Complicato: Calcolatore di Numeri di Fibonacci

Ora che abbiamo fatto i primi passi, proviamo qualcosa di un po' più complicato - un calcolatore di numeri di Fibonacci.

#include <emscripten/emscripten.h>

extern "C" {
EMSCRIPTEN_KEEPALIVE
int fibonacci(int n) {
if (n <= 1) return n;
return fibonacci(n-1) + fibonacci(n-2);
}
}

Questa funzione calcola il numero di Fibonacci nth in modo ricorsivo. Non è il metodo più efficiente, ma è ottimo per la dimostrazione!

Compilalo allo stesso modo di prima, poi chiamalo da JavaScript così:

console.log(Module.ccall('fibonacci', 'number', ['number'], [10]));

Questo dovrebbe stampare il decimo numero di Fibonacci (che è 55, tra l'altro).

Lavorare con Array

Livelliamo il gioco e lavoriamo con array. Ecco una funzione che calcola la somma di un array:

#include <emscripten/emscripten.h>

extern "C" {
EMSCRIPTEN_KEEPALIVE
int sumArray(int* arr, int size) {
int sum = 0;
for (int i = 0; i < size; i++) {
sum += arr[i];
}
return sum;
}
}

Per usarla da JavaScript, dobbiamo fare un po' più di lavoro:

let arr = new Int32Array([1, 2, 3, 4, 5]);
let buffer = Module._malloc(arr.length * arr.BYTES_PER_ELEMENT);
Module.HEAP32.set(arr, buffer >> 2);
let sum = Module.ccall('sumArray', 'number', ['number', 'number'], [buffer, arr.length]);
Module._free(buffer);
console.log(sum);  // Dovrebbe stampare 15

Questo potrebbe sembrare complicato, ma stiamo essenzialmente:

  1. Creando un array in JavaScript
  2. Allocando memoria nell'heap di WebAssembly
  3. Copiando il nostro array in quella memoria
  4. Chiamando la nostra funzione
  5. Liberando la memoria allocata

Conclusione

Congratulazioni! Hai fatto i tuoi primi passi nel mondo di WebAssembly con C++. Abbiamo coperto molto terreno, da un semplice "Ciao, Mondo!" a lavorare con array. Ricorda, imparare a programmare è come imparare una nuova lingua - richiede pratica e pazienza. Non ti scoraggiare se non capisci tutto subito. Continua a sperimentare, a programmare e, soprattutto, a divertirti!

Ecco una tabella che riassume i principali metodi che abbiamo utilizzato:

Metodo Descrizione
emcc Comando del compilatore Emscripten
EMSCRIPTEN_KEEPALIVE Macro per impedire che la funzione venga ottimizzata
Module.ccall Metodo JavaScript per chiamare funzioni C++
Module._malloc Allocare memoria nell'heap di WebAssembly
Module._free Liberare la memoria allocata nell'heap di WebAssembly
Module.HEAP32 Vista Int32Array della memoria di WebAssembly

Ricorda, WebAssembly e C++ aprono un mondo di possibilità per lo sviluppo web. Il cielo è il limite! Continua a programmare, a imparare, e chissà, forse tra pochi anni sarai tu a insegnare questo corso!

Credits: Image by storyset