¿Cómo ejecutar el código C ++ en el navegador usando asm.js?

21

Una aplicación asm.js es muy rápida (casi la velocidad nativa de C ++):

ingrese la descripción de la imagen aquí

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

Pero, ¿cómo es posible escribir uno en C ++, convertirlo a código LLVM y luego hacer algún truco con emscripten / asm.js? No he encontrado ningún tutorial al respecto.

Y si escribo el código en C ++, ¿cómo usar las API de js, por ejemplo XMLHttpRequest, WebSockets, Canvas o WebGL?

LO Kaka
fuente
3
Compartir su investigación ayuda a todos. Cuéntanos qué has probado y por qué no satisfizo tus necesidades. Esto demuestra que te has tomado el tiempo para tratar de ayudarte a ti mismo, nos salva de reiterar respuestas obvias y, sobre todo, te ayuda a obtener una respuesta más específica y relevante. También vea Cómo preguntar
mosquito
Este tutorial de terceros parece abordar algunas de estas preguntas: devosoft.org/an-introduction-to-web-development-with-emscripten
nobar

Respuestas:

36

Creo que se equivoca en su comprensión de asm.js .

Primero, de sus preguntas frecuentes

P. ¿Es asm.js un nuevo idioma?
R. No, es solo (un subconjunto de) JavaScript.

Y pediste aclaraciones añadidas :

Pero, ¿cómo es posible escribir uno [una aplicación asm.js] en C ++

No escribe una "aplicación asm.js", sino que asm.js es un destino 1 para compilar su código C ++.

Este artículo de John Resig proporciona una serie de detalles que pueden explicar mejor cómo se usaría asm.js.

Comenzando con esta imagen:
C ++ => clang / LLVM => emscripten => motor JS

puede ver que asm.js es un objetivo de traducción de emscripten . Emscripten maneja la traducción del código de bytes LLVM a JavaScript, y asm.js es un subconjunto de JavaScript. Mantenerse dentro del subconjunto restringido de JavaScript de asm.js permite que el código se optimice y se ejecute más rápido.

También preguntaste:

Y si escribo el código en C ++, entonces, ¿cómo usar las API-s de js?

De nuevo, te estás perdiendo el punto. Asm.js permite portar aplicaciones C / C ++ existentes a JavaScript para que puedan ejecutarse dentro de un navegador. Normalmente no podría usar las API de JS dentro de su código C / C ++, y no hay nada mágico en asm.js para permitir eso.

Si tiene una nueva aplicación para escribir que necesita API JS, entonces debe escribir la aplicación en JS y no tratar de escribir en C ++ y luego transferir a JavaScript.

Y volviendo al artículo de Resig, hay dos citas clave para su pregunta:

El tipo de aplicaciones que van a apuntar a Asm.js, en el futuro cercano, son aquellas que se beneficiarán de la portabilidad de ejecutarse en un navegador pero que tienen un nivel de complejidad en el que un puerto directo a JavaScript sería inviable

y

Como probablemente pueda ver en el código anterior, Asm.js no está diseñado para ser escrito a mano. ... El caso de uso más común para Asm.js en este momento es en aplicaciones que cumplen con C / C ++ a JavaScript. Casi ninguna de estas aplicaciones interactúa con el DOM de manera significativa, más allá del uso de WebGL y similares.

Lo que quizás desee considerar hacer es tener un programa de JavaScript que llame a las API de JS que necesita junto con realizar llamadas al C ++ que compiló en JavaScript. Eche un vistazo a este tutorial emscripten para ver cómo llamar al código C ++ desde JavaScript.


Para algunas investigaciones adicionales, emscripten tiene un tutorial que puede ayudarlo a comenzar a comprender cómo tomar el código C ++, ejecutarlo a través de LLVM y luego apuntar a asm.js.

1 Hablando estrictamente, eso no es cierto. El código C / C ++ no es consciente de lo que se va a compilar, por lo que realmente no puedo llamar a asm.js como objetivo. Otra herramienta (emscripten) toma la salida LLVM y luego la traduce a JavaScript compatible con asm.js. Pero lo llamaré un objetivo porque es más fácil de entender.

TehShrike
fuente
ASM.js es un objetivo de compilación para C / C ++. Así que no, no estás escribiendo C ++ en asm.js tu compilación de C ++ en asm.js
Calvin
Solo me viene a la mente una mención para las aplicaciones iniciadas desde cero. En el caso de los juegos, tener el código en C ++ podría ser útil para implementar en múltiples plataformas.
Vlad Nicula
6

Sí, puede escribir código C ++ y compilarlo en asm.js, utilizando emscripten. No lo he probado yo mismo, y no estoy seguro de qué tan preparado está para el horario estelar. Sin embargo, parece ser lo suficientemente bueno como para ejecutar un montón de juegos.

Aquí hay un tutorial: http://kripken.github.io/emscripten-site/docs/getting_started/Tutorial.html . Mirando el tutorial, parece bastante fácil compilar código C ++:

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

int main() {
  printf("hello, world!\n");
  return 1;
}
$ ./emcc tests/hello.cpp -o hello.html
jdm
fuente
44
Eso es en realidad el código C. Un compilador de C ++ es aproximadamente dos o tres órdenes de magnitud más complejo. Afortunadamente, emscripten evita ese difícil problema compilando LLVM, y hay un compilador C ++ a LLVM existente.
MSalters
3
@MSalters: también es un código C ++ válido. ¡Imagina eso! ¡Guauu!
Thomas Eding
@ThomasEding: Te perdiste el punto. Cuanto más pequeño sea el idioma que debe admitir, más fácil será compilar ese idioma. La intersección de C y C ++ no es necesariamente más grande que cualquiera de esos dos.
MSalters
Supongamos que este código fuera puro C ++, que un compilador de C no manejaría, ¿ emccsería válido el uso de ?
Hamza Ouaghad
@HamzaOuaghad: sí. un simple mundo hola con las clases cout & string de c ++ funciona bien con esta línea de comando emcc. utilizando la versión 1.35.0.
orion elenzil el
0

La forma más fácil sería usar WCPP , un paquete que le permite importar C ++ casi directamente en su proyecto Node.

Nuestro C ++

// addTwo.cpp 

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

En la terminal (para compilar nuestro C ++)

$ wcpp

Nuestro JavaScript

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

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

Para obtener más información, consulte el paquete NPM o el repositorio de Git

Brandon Dyer
fuente