Una trampa de N hace mucho tiempo, utilizando Node.js para reconstruir el juez en línea de NBUT, incluido el lado de la evaluación, también debe ser reconstruido. (En cuanto a cuándo se completa, no me importa, (/д ′)/~
En resumen, lo que vamos a hacer ahora es usar C/C ++ para implementar módulos Node.js.
Preparación
Si quieres hacer las cosas bien, primero debes actuar como un gángster y afilar tus herramientas.
nodo
Primero necesitas un módulo de nodo-GYP.
En cualquier esquina, ejecute:
La copia del código es la siguiente:
$ npm de instalación de nodo -gyp -g
Después de una serie de blahblahs, lo has instalado.
Pitón
Entonces necesitas tener un entorno de Python.
Vaya al sitio web oficial y obtenga uno.
Nota: Según la pantalla GitHub de Node-Gyp, asegúrese de asegurarse de que su versión de Python esté entre 2.5.0 y 3.0.0.
Entorno de compilación
Bueno, solo soy vago y no lo escribo en detalle. Muévase a Node-Gyp para ver las necesidades del compilador. Y hacer un escándalo.
empezando
Te contaré sobre la introducción al sitio web oficial Hello World.
Hola Mundo
Prepare un archivo C ++, por ejemplo, se llama ~~ sb.cc ~~ hello.cc.
Luego daremos un paso a paso, primero crearemos el archivo de encabezado y definiremos el espacio de nombres:
La copia del código es la siguiente:
#include <node.h>
#Include <v8.h>
usando el espacio de nombres V8;
Funciones principales
A continuación, escribimos una función cuyo valor de retorno es manejo <valor>.
La copia del código es la siguiente:
Manejar <valor> Hello (Const Arguments & Args)
{
// ... tenía hambre de ser escrito
}
Luego analizaré estas cosas aproximadamente:
Manejar <valor>
Debes ser honesto en la vida. Declaro de antemano que me refiero a él desde aquí (@fool).
V8 usa el tipo de identificación para alojar objetos JavaScript. Similar al STD :: SharedPointer de C ++, las asignaciones entre los tipos de mango se aproban directamente las referencias de objetos, pero la diferencia es que V8 usa su propio GC para administrar el ciclo de vida del objeto, en lugar del recuento de referencias comúnmente utilizado por los punteros inteligentes.
Los tipos de JavaScript tienen los tipos personalizados correspondientes en C ++, como cadena, entero, objeto, fecha, matriz, etc., y cumplen estrictamente la relación de herencia en JavaScript. Cuando use estos tipos en C ++, debe usar el alojamiento de Handle para usar GC para administrar sus ciclos de vida sin usar pilas y montones nativos.
Este llamado valor, que se puede ver desde las diversas relaciones de herencia en el archivo de encabezado V8.H del motor V8, es en realidad la clase base de varios objetos en JavaScript.
Después de comprender esto, podemos comprender aproximadamente el significado de la declaración de función anterior, lo que significa que escribimos una función de saludo, que devuelve un valor de un tipo incierto.
Nota: Solo podemos devolver tipos específicos, a saber, cadena, entero, etc. en el alojamiento de mango.
Argumentos
Este es el parámetro que pasará en esta función. Todos sabemos que en Node.js, el número de parámetros es aleatorio. Cuando estos parámetros se pasan a C ++, se convierten en un objeto de tipo de argumentos.
Hablemos sobre el uso específico más adelante. Aquí solo necesitamos entender qué es esto. (¿Para mantenerlo en secreto? Porque los ejemplos en el documento oficial de nodo.js se discuten por separado. Estoy hablando del primer ejemplo de Hello World (´థ౪థ) σ
Agregar ladrillos y azulejos
A continuación comenzamos a contribuir. Solo las oraciones más simples:
La copia del código es la siguiente:
Manejar <valor> Hello (Const Arguments & Args)
{
Alcance de manejo;
return scope.close (string :: new ("mundo"));
}
¿Qué significan estas dos oraciones? El significado general es devolver una cadena "mundo" en Node.js.
Mango
La misma referencia es de aquí.
El ciclo de vida del mango es diferente al de los punteros inteligentes C ++. No sobrevive dentro del alcance de la semántica de C ++ (es decir, la parte rodeada por {}), pero necesita especificarse manualmente a través del Handlescope. El manejo solo se puede asignar en la pila. Después de declararse el objeto Handlescope, el mango creado más tarde se gestiona por Handlescope. Después de destruir el objeto Handlescope, el Many manejado por él será determinado por el GC.
Entonces, tenemos que declarar este alcance cuando necesitamos administrar su ciclo de vida. Ok, entonces, ¿por qué no nuestro código no se escribe así?
La copia del código es la siguiente:
Manejar <valor> Hello (Const Arguments & Args)
{
Alcance de manejo;
return string :: new ("mundo");
}
Porque cuando la función regrese, el alcance será destruido y las manijas que manejan se reciclarán, por lo que esta cadena no tendrá sentido.
Entonces, a V8 se le ocurrió una idea mágica: la función Handlescope :: Close (Handle <T> Value). El propósito de esta función es cerrar el alcance y entregar los parámetros dentro de la gestión del alcance anterior, es decir, el alcance antes de ingresar a esta función.
Entonces tenemos el código anterior Scope.Close (String :: New ("World"));.
Cadena :: nuevo
La clase de cadena corresponde a la clase de cadena nativa en Node.js. Heredado de la clase de valor. Del mismo modo, hay:
•Formación
•Entero
• booleano
•Objeto
•Fecha
•Número
•Función
• ...
Algunas de estas cosas se heredan del valor, mientras que otras se heredan de secundaria. No investigaremos mucho aquí. Puede mirar el código V8 (al menos el archivo de encabezado) o mirar este manual.
¿Y este nuevo? Puedes verlo aquí. Es crear un nuevo objeto de cadena.
En este punto, hemos terminado de analizar esta función principal.
Exportar objetos
Vamos a revisarlo. Si está escrito en Node.js, ¿cómo exportamos funciones u objetos?
La copia del código es la siguiente:
exports.hello = function () {}
Entonces, ¿cómo podemos hacer esto en C ++?
Inicializar la función
Primero, escribamos una función de inicialización:
La copia del código es la siguiente:
Void init (manejar <ject> exportaciones)
{
// ... ¡Tengo hambre de escribir sobre tu hermana! #゚ Å ゚) ⊂ち☆)) ゚ д ゚) ・∵
}
¡Este es un culo de tortuga! No importa si el nombre de la función o algo así, pero el parámetro aprobado debe ser un mango <juego>, lo que significa que exportaremos las cosas de este producto a continuación.
Luego, escribimos lo exportado aquí:
La copia del código es la siguiente:
Void init (manejar <ject> exportaciones)
{
Exports-> set (String :: Newsymbol ("Hola"),
FunctionTemplate :: new (hola)-> getFunction ());
}
El significado general es agregar un campo llamado hola a este objeto de exportación, y la cosa correspondiente es una función, y esta función es nuestra querida función de hola.
Para escribir un punto simple en el código de pseudo:
La copia del código es la siguiente:
Void init (manejar <ject> exportaciones)
{
exports.set ("hola", función hola);
}
¡El trabajo está hecho!
(¡Tu hermana termina! Cállate ('д'⊂☡☆)) д´)
Verdadera exportación
Este es el último paso, y finalmente declararemos que esta es la entrada a la exportación, por lo que agregamos esta línea al final del código:
Node_module (hola, init)
¿Has tomado un NI? ! ¿Qué es esto?
No se preocupe, este node_module es una macro, lo que significa que utilizamos la función de inicialización de init para exportar las cosas que se exportarán a Hello. Entonces, ¿de dónde viene este saludo?
¡Proviene del nombre del archivo! Sí, sí, proviene del nombre del archivo. No necesita declararlo por adelantado, y no tiene que preocuparse por no poder usarlo. En resumen, ¿cuál es el nombre de su archivo binario compilado final? Completará el hola aquí y, por supuesto, debe eliminar el nombre del sufijo.
Vea la documentación oficial para obtener más detalles.
Tenga en cuenta que todas las adiciones de nodo deben exportar una función de inicialización:
La copia del código es la siguiente:
Void Initialize (manejar <ject> exportaciones);
Node_module (módulo_name, inicializar)
No hay semi-colon después de node_module, ya que no es una función (ver node.h).
El módulo_name debe coincidir con el nombre de archivo del binario final (menos el sufijo .node).
Compilar (๑ • ́ ₃ • ̀๑)
¡Vamos, recopilaremos juntos!
Creemos un nuevo archivo de archivo similar a Makefile - Binding.gyp.
Y agregue el código así:
La copia del código es la siguiente:
{
"Objetivos": [
{
"Target_name": "Hola",
"Fuentes": ["Hello.cc"]
}
]
}
¿Por qué escribir esto? Puede consultar la documentación oficial de Node-GYP.
configurar
Después de que el archivo esté listo, necesitamos ejecutar este comando en este directorio:
La copia del código es la siguiente:
$ nodo-gyp configurar
Si todo está bien, se debe generar un directorio de compilación, y luego hay archivos relacionados en el interior, tal vez m $ Visual Studio VCXProj, etc., o tal vez MakFile, dependiendo de la plataforma.
construir
Después de generar el makfile, comenzamos a construir y compilar:
$ nodo-gyp construcción
¡Solo cuando todo esté compilado, se considerará que la tarea real se completa! Si no lo cree, vaya y consulte el directorio de compilación/lanzamiento. ¿Hay un archivo Hello.node a continuación? Así es, este es el jabón que C ++ quiere recoger para Node.js más tarde.
¡Obtenemos lo básico! Nodo (✿゚゚) ノ c ++
Creamos un nuevo archivo jianfeizao.js en el directorio justo ahora:
La copia del código es la siguiente:
var addon = request ("./ build/rotes/hello");
console.log (addon.hello ());
¡Mira o no! ¡Mira o no! ¡Salga! ¡El resultado de Node.js y C ++ obtienen conceptos básicos! Este addon.hello () es el mango <valor> Hello (const argumentos y args) que escribimos en código C ++ antes, y ahora hemos producido el valor que devuelve.
Tomar una ducha e ir a la cama, y la siguiente sección es más profunda
Se está haciendo tarde, así que terminaré escribiendo hoy. Hasta ahora, todos pueden encontrar la extensión Hello World C ++ más básica. La próxima vez que lo escriba, no sé cuándo será la próxima vez.
(Oye, oye, ¿cómo puede el maestro ser tan irresponsable! (O ゚ロ?) ┌┛σ (ノ ´ω`) ノ