Revoir le passé et apprendre le nouveau peut vous rendre heureux
Tout d'abord, n'oubliez pas ce manuel en ligne V8 - http://izs.me/v8-docs/main.html.
Vous souvenez-vous encore du fichier building.gyp de la dernière fois ?
Juste comme ça, si vous avez quelques fichiers *.cc supplémentaires, cela ressemblera à ceci :
"sources": [ "addon.cc", "monexemple.cc" ]
La dernière fois, nous avons séparé les deux étapes. En fait, la configuration et la compilation peuvent être mises ensemble :
$ node-gyp configurer build
Avez-vous fini de réviser ? sans? !
D’accord, continuons.
Table des matières
Paramètres de fonction
Maintenant, nous devons enfin parler des paramètres.
Imaginons qu'il existe une telle fonction add(a, b) qui représente l'ajout de a et b et le renvoi du résultat, alors écrivez d'abord le contour de la fonction :
Poignée
{
Portée HandleScope ;
//... C'est reparti !
>
Arguments
C'est le paramètre de la fonction. Jetons d’abord un coup d’œil à la référence officielle du manuel de la v8.
•int Longueur() const
•Opérateur Local
Le reste on s’en fout, ces deux-là sont importants ! L'un représente le nombre de paramètres passés dans la fonction et l'autre crochet est utilisé pour accéder au nième paramètre via l'index d'indice.
Par conséquent, nous pouvons à peu près comprendre les exigences ci-dessus car args.Length() est 2, args[0] représente a et args[1] représente b. Et nous devons déterminer que le type de ces deux nombres doit être Nombre.
Notez que l'opérateur d'index entre crochets renvoie une Local
•IsArray()
•EstBooléen()
•EstDate()
•EstFonction()
•IsInt32()
•IsNativeError()
•EstNull()
•EstNuméro()
•IsRegExp()
•IsString()
•...
Je ne les listerai pas un par un, vous pouvez lire la documentation pour le reste. 。:.゚ヽ(*´∀`)ノ゚.:。
ThrowException
C'est une fonction que nous utiliserons plus tard. Les détails peuvent être trouvés dans la documentation v8.
Comme son nom l'indique, cela génère une erreur. Après avoir exécuté cette instruction, cela équivaut à exécuter une instruction throw() dans le fichier local Node.js. Par exemple :
ThrowException(Exception::TypeError(String::New("Mauvais nombre d'arguments")));
Cela équivaut à exécuter un Node.js :
throw new TypeError("Mauvais nombre d'arguments");
Non défini()
Cette fonction est également dans la documentation.
Plus précisément, il s'agit d'une valeur nulle, car certaines fonctions n'ont pas besoin de renvoyer de valeur spécifique, ou il n'y a pas de valeur de retour pour le moment, Undefined() doit être utilisé à la place.
Faisons-le, Saonian !
Après avoir compris les points ci-dessus, je pense que vous serez bientôt capable d'écrire la logique de a b. Je copierai le code du manuel officiel de Node.js et vous le donnerai pour que vous puissiez le parcourir :
Poignée
{
Portée HandleScope ;
// signifie que plus de 2 paramètres peuvent être transmis, mais en fait nous n'utilisons que les deux premiers
Si(args.Length() < 2)
{
// erreur de lancement
ThrowException(Exception::TypeError(String::New("Mauvais nombre d'arguments")));
// Renvoie la valeur nulle
return scope.Close(Undefined());
>
// Si l'un des deux premiers paramètres n'est pas un nombre
Si(!args[0]->IsNumber() || !args[1]->IsNumber())
{
// Génère une erreur et renvoie une valeur nulle
ThrowException(Exception::TypeError(String::New("Wrong arguments")));
return scope.Close(Undefined());
>
// Veuillez vous référer à la documentation v8 pour plus de détails
// http://izs.me/v8-docs/classv8_1_1Value.html#a6eac2b07dced58f1761bbfd53bf0e366)
// Fonction `NumberValue`
Local
return scope.Close(num);
>
La fonction est terminée !
Enfin, écrivez la fonction d’export à la fin et c’est OK.
Vous verrez un 2b ! ✧。٩(ˊᗜˋ)و✧*。
Fonction de rappel
Dans le dernier chapitre, nous n'avons parlé que de Hello World. Dans ce chapitre, grand-mère a fait une découverte consciente et a écrit une autre fonction de rappel.
Comme d'habitude, nous écrivons d'abord le framework :
Handle
{
Portée HandleScope ;
// ... crépitement crépitement
return scope.Close(Undefined());
>
Ensuite nous avons décidé de l'utiliser comme ceci :
func(fonction(msg) {
console.log(msg);
});
Autrement dit, il transmettra un paramètre à la fonction de rappel. Nous imaginons qu'il s'agit d'une chaîne, puis nous pourrons la console.log().
Vous devez d'abord avoir une série de chaînes
Sans plus attendre, alimentons-le d'abord en chaîne, puis parlons-en. (√ζε:)
Mais nous devons faire de cette chaîne un type universel, car le code Node.js est faiblement typé.
Local
Quoi ? Vous me demandez ce qu'est Local
Alors laissez-moi en parler un peu, référez-vous-y ici et au document de référence V8.
Comme indiqué dans la documentation, Local
Alors parlons du Local.
Il existe deux types de handle, Local Handle et Persistent Handle. Les types sont Local
Ensuite, vous devez avoir une série de tableaux de paramètres
Comment obtenir les paramètres de ligne de commande après avoir appelé C/C depuis la ligne de commande du terminal ?
void main(int argc, char* argv[])
{
// ...
>
Au fait, argc est ici le nombre de paramètres de ligne de commande, et argv[] est chaque paramètre. En appelant ensuite la fonction de rappel de Node.js, la v8 utilise également une méthode similaire :
~~QAQ est bloqué dans Handle
Après l'avoir vérifié sous de nombreux aspects (SegmentFault, StackOverflow et un groupe KouKou), j'ai finalement résolu la signification des trois paramètres de la fonction ci-dessus.
Je ne dirai pas grand-chose sur les deux paramètres suivants. L'un est le nombre de paramètres et l'autre est un tableau de paramètres. Quant au premier paramètre Handle
C'est la même chose que d'appliquer en JS. En JS, vous le faites
.
L'objet passé comme premier argument devient ceci dans la portée de la fonction. Plus de documentation sur MDN Si vous ne connaissez pas bien JS, vous pouvez en savoir plus sur JS ici : http://unschooled.org. /2012/03/comprendre-javascript-this/
——Extrait de StackOverflow
En bref, sa fonction est de spécifier le pointeur this de la fonction appelée. L'utilisation de cet appel est similaire à bind(), call() et apply() en JavaScript.
Ce que nous devons donc faire est de construire d'abord la table des paramètres, puis de transmettre la fonction Call pour exécution.
La première étape consiste à afficher la fonction de conversion, car il s'agit à l'origine d'un type Objet :
Local
La deuxième étape consiste à créer une table de paramètres (array) :
Local
Série de fonctions de dernier appel
Appelez cb et passez les paramètres dans :
cb->Call(Context::GetCurrent()->Global(), 1, argv);
Le premier paramètre ici, Context::GetCurrent()->Global(), signifie obtenir le contexte global comme celui de la fonction ; le deuxième paramètre est le numéro dans la table des paramètres (après tout, bien que Node.js Le tableau a un attribut de longueur, mais le système ne connaît pas en fait la longueur du tableau en C, et vous devez transmettre vous-même un nombre pour indiquer la longueur du tableau ; le dernier paramètre est la table de paramètres que nous venons de créer) ; .
Série de documents finaux du chapitre final
Je pense que tout le monde connaît déjà cette étape, qui consiste à écrire la fonction, puis à la mettre dans la fonction exportée, et enfin à la déclarer.
Je vais simplement publier le code directement, ou vous pouvez accéder directement à la documentation Node.js.
Handle
{
Portée HandleScope ;
Local
const argc non signé = 1;
Local
cb->Call(Context::GetCurrent()->Global(), argc, argv);
return scope.Close(Undefined());
>
void Init (exports Handle
NODE_MODULE(module complémentaire, Init)
Bravo ! Faites simplement les dernières étapes restantes vous-même. Quant à l’appel de cette fonction en JS, je l’ai déjà mentionné.
Extra
Eh bien, j'ai l'impression que mes notes d'étude deviennent de plus en plus libres. S'il vous plaît, décomposez-les ~
.Arrêtons-nous ici aujourd'hui. En train de rédiger des notes d'étude, j'ai encore eu des ennuis, comme la signification des paramètres de la fonction Call.
Si vous pensez que cette série de notes d'étude vous est toujours utile, venez me rejoindre pour vous amuser ~Σ>―(〃°ω°〃)♡→