Comment exécuter du code C ++ dans un navigateur en utilisant asm.js?

21

Une application asm.js est très rapide (proche de la vitesse native C ++):

entrez la description de l'image ici

http://kripken.github.io/mloc_emscripten_talk/micro4b.png

Mais comment est-il possible d'en écrire un en C ++, de le convertir en code LLVM, puis de faire un tour avec emscripten / asm.js? Je n'ai trouvé aucun tutoriel à ce sujet.

Et si j'écris le code en C ++, alors comment utiliser les API js, par exemple XMLHttpRequest, WebSockets, Canvas ou WebGL?

LO kaka
la source
3
Partager vos recherches aide tout le monde. Dites-nous ce que vous avez essayé et pourquoi cela n'a pas répondu à vos besoins. Cela démontre que vous avez pris le temps d'essayer de vous aider, cela nous évite de répéter des réponses évidentes et, surtout, cela vous aide à obtenir une réponse plus spécifique et plus pertinente. Voir aussi Comment demander
moucher
Ce didacticiel tiers semble répondre à certaines de ces questions: devosoft.org/an-introduction-to-web-development-with-emscripten
nobar

Réponses:

36

Je crois que vous vous trompez dans votre compréhension de asm.js .

Tout d'abord, à partir de leur FAQ

Q. asm.js est-il une nouvelle langue?
R. Non, c'est juste (un sous-ensemble de) JavaScript.

Et vous avez demandé des éclaircissements ajoutés :

Mais comment est-il possible d'en écrire une [une application asm.js] en C ++

Vous n'écrivez pas une "application asm.js", mais asm.js est une cible 1 pour compiler votre code C ++.

Cet article de John Resig fournit un certain nombre de détails qui pourraient mieux expliquer comment asm.js serait utilisé.

En commençant par cette image:
C ++ => clang / LLVM => emscripten => moteur JS

vous pouvez voir que asm.js est une cible de traduction pour emscripten . Emscripten gère la traduction du bytecode LLVM en JavaScript, et asm.js est un sous-ensemble de JavaScript. Rester dans le sous-ensemble restreint de asm.js de JavaScript permet d'optimiser le code et de l'exécuter plus rapidement.

Vous avez également demandé:

Et si j'écris le code en C ++, alors comment utiliser les API js

Encore une fois, vous manquez le point. Asm.js permet de porter des applications C / C ++ existantes en JavaScript afin qu'elles puissent être exécutées dans un navigateur. Normalement, vous ne pourriez pas utiliser les API JS dans votre code C / C ++, et il n'y a rien de magique dans asm.js pour permettre cela.

Si vous avez une nouvelle application à écrire qui a besoin d'API JS, vous devez écrire l'application en JS et non futz en essayant d'écrire en C ++, puis de la porter en JavaScript.

Et pour revenir à l'article de Resig, il y a deux citations clés pour votre question:

le type d'applications qui cibleront Asm.js, dans un avenir proche, sont celles qui bénéficieront de la portabilité de l'exécution dans un navigateur mais qui ont un niveau de complexité dans lequel un port direct vers JavaScript serait irréalisable

et

Comme vous pouvez probablement le voir dans le code ci-dessus, Asm.js n'est pas conçu pour être écrit à la main. ... Le cas d'utilisation le plus courant pour Asm.js est actuellement dans les applications conformes de C / C ++ à JavaScript. Presque aucune de ces applications n'interagit avec le DOM de manière significative, au-delà de l'utilisation de WebGL et similaires.

Ce que vous voudrez peut-être envisager à la place, c'est d'avoir un programme JavaScript qui appelle les API JS dont vous avez besoin, ainsi que des appels au C ++ que vous avez compilé en JavaScript. Jetez un œil à ce didacticiel emscripten pour voir comment appeler du code C ++ à partir de JavaScript.


Pour quelques recherches supplémentaires, emscripten propose un didacticiel qui pourrait vous aider à comprendre comment prendre le code C ++, l'exécuter via LLVM, puis cibler asm.js.

1 Strictement parlant, ce n'est pas vrai. Le code C / C ++ ne sait pas à quoi il va être compilé, donc je ne peux pas vraiment appeler asm.js une cible. Un autre outil (emscripten) prend la sortie LLVM puis traduit en JavaScript compatible asm.js. Mais je vais appeler cela un objectif car il est plus facile à comprendre.

TehShrike
la source
ASM.js est une cible de compilation pour C / C ++. Donc non, vous n'écrivez pas C ++ dans asm.js, votre compilation C ++ dans asm.js
Calvin
Une seule mention vient à l'esprit pour les applications démarrées à partir de zéro. Dans le cas des jeux, avoir le code en C ++ pourrait être utile pour le déploiement sur plusieurs plateformes.
Vlad Nicula
6

Oui, vous pouvez écrire du code C ++ et le compiler dans asm.js, en utilisant emscripten. Je ne l'ai pas essayé moi-même et je ne sais pas à quel point c'est prêt pour les heures de grande écoute. Il semble cependant être assez bon pour exécuter un tas de jeux.

Voici un tutoriel: http://kripken.github.io/emscripten-site/docs/getting_started/Tutorial.html . En regardant le tutoriel, il semble assez facile de compiler du code C ++:

// hello.cpp
#include<stdio.h>

int main() {
  printf("hello, world!\n");
  return 1;
}
$ ./emcc tests/hello.cpp -o hello.html
jdm
la source
4
C'est en fait du code C. Un compilateur C ++ est environ deux ou trois ordres de grandeur plus complexe. Heureusement, emscripten évite ce problème difficile en compilant LLVM, et il existe un compilateur C ++ vers LLVM existant.
MSalters
3
@MSalters: C'est aussi du code C ++ valide. Imagine ça! Hou la la!
Thomas Eding
@ThomasEding: Vous avez raté le point. Plus la langue que vous devez prendre en charge est petite, plus il est facile de compiler cette langue. L'intersection de C et C ++ n'est nécessairement pas plus grande que ces deux-là.
MSalters
Supposons que ce code soit du C ++ pur, qu'un compilateur C ne gère pas, l'utilisation de emccserait-elle valide?
Hamza Ouaghad
@HamzaOuaghad - oui. un simple bonjour avec les classes cout & string de c ++ fonctionne très bien avec cette ligne de commande emcc. en utilisant la version 1.35.0.
orion elenzil
0

La façon la plus simple serait d'utiliser WCPP , un package qui vous permet d'importer C ++ presque directement dans votre projet Node.

Notre C ++

// addTwo.cpp 

export int addTwo(int a, int b) {
  return a + b;
}

Dans le terminal (pour compiler notre C ++)

$ wcpp

Notre JavaScript

const ourModule = await require('wcpp')('./addTwo.cpp')

console.log(ourModule.addTwo(2, 3))

Pour plus d'informations, consultez le NPM Package ou le Git Repo

Brandon Dyer
la source