Convertir C++ en WebAssembly
Développer un vrai programme C++ exécutable localement.
Vous trouverez de nombreux exemples sur le Web qui prétendent montrer comment réaliser une application wasm à partir d'un fichier source C++. Mais à y mieux regarder, ce sont toujours des codes sources C. Pour avoir ic un exemple de vrai code C++, nous allons ajouter une fonction qui ne peut exister en C puisqu'elle utilise le type string pour stocker une chaîne de caractère à la place de char * du langage C.
Notre exemple de bibliothèque C++ inclut une fonction concat dont l'intérêt est purement démonstratif...
#include <string>
using namespace std;
int add(int x, int y) {
return x + y;
}
int mul(int x, int y) {
return x * y;
}
float divide(int x, int y) {
if(y == 0) return 0;
return x / y;
}
string concat(string a, string b) {
return a + b;
}
On inclut l'en-tête string propre à C++ et l'espace de nom std. Ce code est sauvé dans le fichier lib.cpp.
On crée aussi un en-tête dans lib.hpp pour pouvoir inclure ce code dans un projet. Voici son contenu:
int add(int, int);
int mul(int, int);
float divide(int, int);
string concat(string, string);
Maintenant, un exemple d'application utilisant cette bibliothèque C++:
/* Demo C++ */
#include <iostream>
#include <string>
using namespace std;
#include "lib.hpp"
int main() {
int a = add(10, 20);
cout << "10 + 20 = " << a << endl;
int m = mul(10, 20);
cout << "10 x 20 = " << m << endl;
float d = divide(30, 10);
cout << "30 / 10 = " << d << endl;
string s = concat("Hello", " World!");
cout << "Concat: " << s << endl;
}
La déclaration de l'espace de nom std doit précéder l'inclusion de l'en-tête arithm.hpp, car il fait référence au type string.
Le source est sauvegardé dans le fichier demo.cpp.
L'application wasm est générée avec la commande suivante:
emcc lib.cpp demo.cpp -o demo.wasm
On exécute le programme avec cette commande:
wasmer demo.wasm
Cela doit afficher les lignes suivantes dans la console:
10 + 20 = 30
10 x 20 = 200
30 / 10 = 3
Concat: Hello World!
L'avantage avec une application locale exécutée par wasmer ou wasmtime est qu'ils savent comment inclure le runtime WASI qui contient la bibliothèque standard C++.
Mais si on veut utiliser une bibliothèque wasm dans une application HTML ou avec node.js, il faudra relier soi-même WASI au code wasm et ce sera plus compliqué, c'est pourquoi une pseudo application C++ qui est en réalité un code C dans un fichier C++ est insuffisante comme exemple. Elle devrait contenir du code propre à C++.