Revisa lo viejo y aprende lo nuevo, puedes mojarte
En primer lugar, recuerde este manual en línea de V8 - http://izs.me/v8-docs/main.html.
¿Recuerdas el último archivo Building.gyp?
La copia del código es la siguiente:
{
"Objetivos": [
{
"Target_name": "complemento",
"Fuentes": ["Addon.cc"]
}
]
}
Solo así, aprende de un ejemplo y aprende de él. Si tiene más archivos *.cc, será así:
"Fuentes": ["Addon.cc", "myExample.cc"]
La última vez que separamos los dos pasos, y de hecho, la configuración y la compilación se pueden juntar:
$ nodo-gyp configurar compilación
¿Has terminado de revisar? ¿sin? !
Ok, entonces sigamos.
Tabla de contenido
Parámetros de función
Ahora finalmente vamos a hablar sobre parámetros.
Imaginemos que hay una función ADD (A, B) que representa agregar A y B para devolver el resultado, así que escriba primero la función de la marco externo:
La copia del código es la siguiente:
#include <node.h>
usando el espacio de nombres V8;
Manejar <valor> add (const argumentos y args)
{
Alcance de manejo;
// ... ¡Ven de nuevo!
}
Argumentos
Este es el parámetro de la función. Echemos un vistazo a la referencia manual oficial de V8 primero.
• int long () const
• Operador local <valor> [] (int i) const
No nos importan los demás, ¡estos dos son muy importantes! Uno representa el número de parámetros pasados en la función, y el otro son los soportes que acceden al enésimo parámetro a través del índice de subíndice.
Entonces, en cuanto a los requisitos anteriores, podemos comprender aproximadamente que args.length () es 2, args [0] representa a y args [1] representa b. Y debemos juzgar que el tipo de estos dos números debe ser número.
No estoy seguro, el operador de índice en el soporte devuelve el resultado de un local <valor>, que es la clase base de todos los tipos de node.js. Por lo tanto, si los parámetros pasados son de tipo variable, debemos juzgar qué parámetros son. Esto está relacionado con algunas funciones de este tipo de valor.
• isarray ()
• Isboolean ()
• IsDate ()
• Isfunction ()
• isInt32 ()
• IsnativeRor ()
• Isnull ()
• IsNumber ()
• ISREGEXP ()
• isstring ()
• ...
No los enumeraré a todos, leeré el resto por mí mismo. 。 :. ゚ (*´∀`) ノ゚ .:。
Throwexception
Esta es una función que usaremos más tarde. Específicamente, se puede encontrar en la documentación V8.
Como su nombre indica, está lanzando un error. Después de ejecutar esta declaración, es equivalente a ejecutar una instrucción SHONE () en el archivo Node.js local. Por ejemplo:
ShoweException (excepción :: typeError (string :: new ("Número incorrecto de argumentos")));
Es equivalente a ejecutar un nodo.js:
tirar nuevo typeError ("número incorrecto de argumentos");
Indefinido()
Esta función también está en el documento.
Específicamente, es un valor nulo, porque algunas funciones no necesitan devolver ningún valor específico o no devolver un valor. En este momento, Undefined () debe usarse en su lugar.
¡Tomar medidas!
Después de comprender los puntos anteriores, creo que pronto podrá escribir la lógica de A + B. Copiaré el código del manual oficial de node.js y lo leeré por usted. Se hará:
La copia del código es la siguiente:
#include <node.h>
usando el espacio de nombres V8;
Manejar <valor> add (const argumentos y args)
{
Alcance de manejo;
// Significa que se pueden pasar más de 2 parámetros, pero de hecho solo usamos los dos primeros
if (args.length () <2)
{
// tirar un error
ShoweException (excepción :: typeError (string :: new ("Número incorrecto de argumentos")));
// devolver el valor vacío
return scope.close (undefinado ());
}
// Si uno de los dos primeros parámetros no es un número
if (! args [0]-> isNumber () ||! args [1]-> isNumber ()))
{
// arrojar un error y devolver un valor nulo
ShoweException (excepción :: typeError (string :: new ("Argumentos incorrectos")));
return scope.close (undefinado ());
}
// Para más detalles, consulte la documentación V8
// http://izs.me/v8-docs/classv8_1_1value.html#a6eac2b07dced58f1761bbfd53bf0e366)
// función `numberValue`
Local <Number> num = number :: new (args [0]-> numberValue () + args [1]-> numberValue ());
return scope.close (num);
}
¡La función está hecha!
Finalmente, escriba la función de exportación al final y estará bien.
La copia del código es la siguiente:
Void init (manejar <ject> exportaciones)
{
Exports-> set (String :: Newsymbol ("agregar"),
FunctionTemplate :: new (add)-> getFunction ());
}
Node_module (addon, init)
Después de compilar, podemos usarlo así:
La copia del código es la siguiente: var addon = request ('./ build/rotes/addon');
console.log (addon.add (1, 1) + "b");
¡Verás un 2B! ✧。٩ (ᗜ) و✧*.
Función de devolución de llamada
En el capítulo anterior, solo hablamos de Hello World. En este capítulo, el maestro de la abuela lo descubrió con conciencia y escribió una función de devolución de llamada.
Para la convención, escribamos primero un marco:
La copia del código es la siguiente:
#include <node.h>
usando el espacio de nombres V8;
Manejar <valor> runcallback (const argumentos y args)
{
Alcance de manejo;
// ... Crackle Crackle Crackle Crackle Crackle Crackle Crackle
return scope.close (undefinado ());
}
Luego decidimos cómo se usa así:
func (function (msg) {
console.log (msg);
});
Es decir, pasará un parámetro a la función de devolución de llamada, imaginamos que es una cadena y luego podemos console.log () para verlo.
Primero necesitas una serie de cadenas
Sin más preámbulos, primero alimentemos una cuerda. (√ ζ ε :)
Pero tenemos que hacer esta cadena de tipos genéricos porque el código Node.js es débil.
Local <valor> :: new (String :: New ("Hello World"));
¿Qué? ¿Me preguntas qué es local <valor>?
Luego hablaré un poco de eso, consulte los documentos de referencia desde aquí y V8.
Como muestra la documentación, Local <T> realmente hereda de Handle <T>, y recuerdo que el capítulo anterior ya había hablado sobre Handle <T>.
Entonces aquí está el local.
Hay dos tipos de mango, mango local y mango persistente, que son locales <t>: manejar <t> y persistente <t>: mango <t>. No hay diferencia entre el primero y el manejo <t> y ambos ciclos de supervivencia están dentro del alcance. El ciclo de vida de este último está separado del alcance, debes llamar manualmente persistente :: Desechar para terminar su ciclo de vida. En otras palabras, el mango local es equivalente a asignar objetos en la pila en C ++ `y el mango persistente es equivalente a los objetos de asignación de C ++ en el montón.
Entonces necesita una serie de tabla de parámetros
¿Cómo obtener los parámetros de la línea de comando después de llamar a C/C ++ en la línea de comandos del terminal?
La copia del código es la siguiente:
#Include <stdio.h>
void main (int argc, char* argv [])
{
// ...
}
Por cierto, el ARGC aquí es el número de parámetros de línea de comandos, y Argv [] son los diversos parámetros. Luego, V8 también usa un método similar a la función de devolución de llamada de Node.js: JS:
La copia del código es la siguiente: V8Export local <valor> v8 :: function :: call (manejar <ject> recv,
int argc,
Manejar <valor> argv []
);
~~ Qaq está atascado en el mango <S Object> Recv! ! ! Sigue escribiendo mañana. ~~
Bueno, comienza el nuevo día y siento que estoy lleno de fuerza. (∩^o^) ⊃━☆゚.*・。。
Después de haber verificado en muchos aspectos (segmentfault, stackoverflow y un grupo QQ), finalmente resolví el significado de los tres parámetros de la función anterior.
No hablaré sobre los dos últimos parámetros, uno es el número de parámetros, y el otro es una variedad de parámetros. En cuanto al primer parámetro de manejo <s object> recv, la explicación de Stackoverflow Brother es la siguiente:
Es lo mismo que se aplica en JS. En JS, tu haces
La copia del código es la siguiente:
contexto var = ...;
cb.apply (contexto, [... args ...]);
El objeto pasó cuando el primer argumento se convierte en esto dentro del alcance de la función. Más documentación sobre MDN. Si no conoce bien a JS, puede leer más sobre esto aquí: http://unschooled.org/2012/03/understanding-javascript-this/
- Extraído de Stackoverflow
En resumen, su función es especificar este puntero a la función llamada. El uso de esta llamada es similar a bind (), llamar () y aplicar () en JavaScript.
Entonces, lo que tenemos que hacer es construir primero la tabla de parámetros y luego pasar esta función de llamada para su ejecución.
El primer paso es mostrar la función de conversión, porque originalmente era un tipo de objeto:
Local <funional> cb = local <función> :: cast (args [0]);
El segundo paso es crear una tabla de parámetros (matriz):
Local <value> argv [argc] = {local <value> :: new (String :: New ("Hello World"))};
La llamada final a la serie de funciones
Llame a CB y pase los parámetros en:
cb-> call (context :: getCurrent ()-> global (), 1, argv);
El primer parámetro aquí contexto :: getCurrent ()-> global () significa obtener esta función del contexto global; El segundo parámetro es el número en la tabla de parámetros (después de todo, aunque la matriz de Node.js tiene un atributo de longitud, el sistema en realidad no conoce la longitud de la matriz en C ++, y debe pasar en un número para explicar la longitud de la matriz); El último parámetro es la tabla de parámetros que acabamos de establecer.
Serie de archivos final del capítulo final
Creo que todos ya están familiarizados con este paso, simplemente escriban la función, luego la pongan en la función de exportación y finalmente la declaran.
Publicaré el código o simplemente iré al documento Node.js para leerlo.
La copia del código es la siguiente:
#include <node.h>
usando el espacio de nombres V8;
Manejar <valor> runcallback (const argumentos y args)
{
Alcance de manejo;
Local <funional> cb = local <función> :: cast (args [0]);
const sin firmar argc = 1;
Local <value> argv [argc] = {local <value> :: new (String :: New ("Hello World"))};
cb-> call (context :: getCurrent ()-> global (), argc, argv);
return scope.close (undefinado ());
}
void init (manejar <ject> exportaciones, manejar el módulo <S Object>)
{
módulo-> set (string :: newSymbol ("exportaciones"),
FunctionTemplate :: new (runCallback)-> getFunction ());
}
Node_module (addon, init)
¡Bien hecho! Vamos a los últimos pasos tú mismo. En cuanto a llamar a esta función en JS, lo he mencionado antes.
Extra
Bueno, siento que mis notas de estudio se están volviendo cada vez más desenfrenadas y quieren romperlas ~
Detengamos aquí hoy. Durante el proceso de escritura de notas de estudio, he aumentado mi postura nuevamente, como el significado del parámetro de la función de llamada.
Si cree que esta serie de notas de estudio es útil para usted, ven y diviértase conmigo ~ σ> (〃 ° Ω ° 〃) ♡ →