Un piège de N il y a longtemps - en utilisant Node.js pour reconstruire le juge en ligne de NBUT, y compris le côté de l'évaluation, doit également être reconstruit. (Quant à quand il est terminé, ne vous souciez pas, (/ д ') / ~
En bref, ce que nous allons faire maintenant, c'est utiliser C / C ++ pour implémenter les modules Node.js.
Préparation
Si vous voulez bien faire les choses, vous devez d'abord agir comme un gangster et affiner vos outils.
gypne de nœuds
Vous avez d'abord besoin d'un module de gyp nœud.
Dans n'importe quel coin, exécutez:
La copie de code est la suivante:
$ npm installer le nœud-gyp -g
Après une série de blahblahs, vous l'avez installé.
Python
Ensuite, vous devez avoir un environnement Python.
Allez sur le site officiel et obtenez-en un.
Remarque: Selon l'affichage GitHub de Node-Gyp, assurez-vous de vous assurer que votre version Python se situe entre 2.5.0 et 3.0.0.
Environnement de compilation
Eh bien, je suis juste paresseux et je ne l'écrit pas en détail. Veuillez passer à Node-Gyp pour voir les besoins du compilateur. Et faire un bruit.
commencer
Je vais vous parler de l'introduction du site officiel Hello World.
Bonjour le monde
Veuillez préparer un fichier C ++, par exemple, il s'appelle ~~ sb.cc ~~ Hello.cc.
Ensuite, nous ferons un pas par étape, créez d'abord le fichier d'en-tête et définirons l'espace de noms:
La copie de code est la suivante:
#include <node.h>
#include <v8.h>
Utilisation de l'espace de noms v8;
Fonctions principales
Ensuite, nous écrivons une fonction dont la valeur de retour est la manche <value>.
La copie de code est la suivante:
Manipuler <value> Bonjour (construts et arguments)
{
// ... avait faim d'être écrit
}
Ensuite, je vais analyser ces choses grossièrement:
Manipuler <value>
Vous devez être honnête dans la vie. Je déclare à l'avance que j'y réfère à partir d'ici (@fool).
V8 utilise le type de manche pour héberger des objets JavaScript. Semblable à STD :: SharedPointer de C ++, les affectations entre les types de manche sont directement passées, mais la différence est que V8 utilise son propre GC pour gérer le cycle de vie de l'objet, plutôt que le nombre de références couramment utilisé par les pointeurs intelligents.
Les types JavaScript ont des types personnalisés correspondants en C ++, tels que String, Integer, Object, Date, Array, etc., et respectent strictement la relation d'hérédité en JavaScript. Lorsque vous utilisez ces types en C ++, vous devez utiliser l'hébergement de poignée pour utiliser GC pour gérer leurs cycles de vie sans utiliser de piles et de tas natifs.
Cette soi-disant valeur, qui peut être vue à partir des différentes relations d'héritage dans le fichier d'en-tête V8.h du moteur V8, est en fait la classe de base de divers objets en JavaScript.
Après avoir compris cela, nous pouvons comprendre à peu près la signification de l'instruction de fonction ci-dessus, ce qui signifie que nous écrivons une fonction Hello, qui renvoie une valeur d'un type incertain.
Remarque: Nous ne pouvons retourner que des types spécifiques, à savoir la chaîne, le nombre entier, etc. sous l'hébergement de la poignée.
Arguments
Il s'agit du paramètre à passer dans cette fonction. Nous savons tous que dans Node.js, le nombre de paramètres est aléatoire. Lorsque ces paramètres sont passés en C ++, ils sont convertis en un objet de type d'arguments.
Parlons de l'utilisation spécifique plus tard. Ici, nous avons juste besoin de comprendre ce que c'est. (Pour garder cela secret? Parce que les exemples du document officiel Node.js sont discutés séparément. Je parle juste du premier exemple de Hello World (´థ౪థ) σ
Ajouter des briques et des carreaux
Ensuite, nous commençons à contribuer. Juste les phrases les plus simples:
La copie de code est la suivante:
Manipuler <value> Bonjour (construts et arguments)
{
Porce de capuche;
return scope.close (string :: new ("world"));
}
Que signifient ces deux phrases? Le sens général est de renvoyer une chaîne "monde" dans Node.js.
Come de poignée
La même référence est d'ici.
Le cycle de vie de la poignée est différent de celui des pointeurs intelligents C ++. Il ne survit pas dans le cadre de la sémantique C ++ (c'est-à-dire la partie entourée de {}), mais doit être spécifié manuellement via Handlescope. Handlescope ne peut être alloué que sur la pile. Une fois l'objet Handlescope déclaré, la poignée créée ultérieurement est gérée par Handlescope. Une fois que l'objet Handlescope a été détruit, la poignée gérée par elle sera déterminée par le GC.
Nous devons donc déclarer cette portée lorsque nous devons gérer son cycle de vie. Ok, alors pourquoi notre code ne sera-t-il pas écrit comme ça?
La copie de code est la suivante:
Manipuler <value> Bonjour (construts et arguments)
{
Porce de capuche;
return string :: new ("world");
}
Parce que lorsque la fonction reviendra, la portée sera détruite et les poignées qu'elle gère sera recyclée, donc cette chaîne deviendra dénuée de sens.
V8 a donc proposé une idée magique - la fonction Handlescope :: Fermer (manche <T> Valeur)! Le but de cette fonction est de fermer la portée et de remettre les paramètres à l'intérieur de la gestion de la portée précédente, c'est-à-dire la portée avant d'entrer dans cette fonction.
Nous avons donc le code précédent Scope.Close (String :: New ("World"));.
String :: Nouveau
La classe String correspond à la classe de chaîne native dans node.js. Hérité de la classe de valeur. De même, il y a:
•Tableau
•Entier
• booléen
•Objet
•Date
•Nombre
•Fonction
• ...
Certaines de ces choses sont héritées de la valeur, tandis que d'autres sont héritées du secondaire. Nous ne ferons pas beaucoup de recherches ici. Vous pouvez consulter le code V8 (au moins le fichier d'en-tête) ou consulter ce manuel.
Et qu'en est-il de ce nouveau? Vous pouvez le voir ici. C'est pour créer un nouvel objet String.
À ce stade, nous avons terminé l'analyse de cette fonction principale.
Exporter des objets
Prenons-le. S'il est écrit dans Node.js, comment exporter des fonctions ou des objets?
La copie de code est la suivante:
export.hello = function () {}
Alors, comment pouvons-nous faire cela en C ++?
Initialiser la fonction
Tout d'abord, écrivons une fonction d'initialisation:
La copie de code est la suivante:
void init (manche <objet> exportations)
{
// ... j'ai faim d'écrire sur ta sœur! # ゚ Å ゚) ⊂ち☆)) ゚ д ゚) ・∵
}
C'est un cul de tortue! Peu importe si le nom de la fonction ou quelque chose, mais le paramètre passé doit être une poignée <objet>, ce qui signifie que nous exporterons les choses de ce produit ci-dessous.
Ensuite, nous écrivons la chose exportée ici:
La copie de code est la suivante:
void init (manche <objet> exportations)
{
Exports-> set (String :: Newsymbol ("Hello"),
FunctionTemplate :: new (Hello) -> getFunction ());
}
La signification générale est d'ajouter un champ appelé Hello à cet objet d'exportation, et la chose correspondante est une fonction, et cette fonction est notre chère fonction Hello.
Pour écrire un point simple dans le pseudo-code:
La copie de code est la suivante:
void init (manche <objet> exportations)
{
export.set ("bonjour", fonction bonjour);
}
Le travail est terminé!
(Ta soeur a terminé! Tais-toi ('д'⊂☡☆)) д´)
Vraie exportation
C'est la dernière étape, et nous déclarerons enfin que c'est l'entrée de l'exportation, nous ajoutons donc cette ligne à la fin du code:
Node_module (bonjour, init)
Avez-vous pris un ni? ! Qu'est-ce que c'est?
Ne vous inquiétez pas, ce node_module est une macro, ce qui signifie que nous utilisons la fonction d'initialisation d'initialisation pour exporter les choses à exporter dans Hello. Alors, d'où vient ce bonjour?
Il vient du nom du fichier! Oui, oui, il provient du nom du fichier. Vous n'avez pas besoin de le déclarer à l'avance et vous n'avez pas à vous soucier de ne pas pouvoir l'utiliser. En bref, quel est le nom de votre fichier binaire compilé final? Vous remplisserez le bonjour ici, et bien sûr, vous devez supprimer le nom du suffixe.
Voir la documentation officielle pour plus de détails.
Notez que tout le nœud ajoute doit exporter une fonction d'initialisation:
La copie de code est la suivante:
void initialiser (manche <objet> exportations);
Node_module (module_name, initialize)
Il n'y a pas de semi-colon après node_module car ce n'est pas une fonction (voir node.h).
Le module_name doit correspondre au nom de fichier du binaire final (moins le suffixe .Node).
Compiler (๑ • ́ ₃ • ̀๑)
Allez, compilons ensemble!
Créons un nouveau fichier d'archive similaire à MakeFile - Binding.gyp.
Et ajoutez le code comme ceci:
La copie de code est la suivante:
{
"cibles": [
{
"cible_name": "bonjour",
"Sources": ["Hello.cc"]
}
]]
}
Pourquoi écrire ceci? Vous pouvez vous référer à la documentation officielle de Node-Gyp.
configurer
Une fois le fichier prêt, nous devons exécuter cette commande dans ce répertoire:
La copie de code est la suivante:
$ Node-Gyp Configurer
Si tout va bien, un répertoire de construction doit être généré, puis il y a des fichiers connexes à l'intérieur, peut-être le fichier VCXProj M $ Visual Studio, etc., ou peut-être MakeFile, selon la plate-forme.
construire
Une fois le makefile généré, nous commençons à construire et à compiler:
$ Node-Gyp Build
Ce n'est que lorsque tout sera compilé sera considéré que la vraie tâche est terminée! Si vous ne le croyez pas, allez consulter le répertoire de build / libération. Y a-t-il un fichier Hello.Node ci-dessous? C'est vrai, c'est le savon que C ++ veut ramasser pour Node.js plus tard!
Allons les bases! Node (✿゚゚) ノ C ++
Nous créons un nouveau fichier jianfeizao.js dans le répertoire tout à l'heure:
La copie de code est la suivante:
var adddon = require ("./ build / release / hello");
console.log (addon.hello ());
Voyez-le ou non! Voyez-le ou non! Sortir! Le résultat de Node.js et C ++ obtenant des bases! Cet addon.hello () est la poignée <value> bonjour (construts et arguments et args) que nous avons écrits dans le code C ++ auparavant, et nous avons désormais publié la valeur qu'il renvoie.
Prenez une douche et allez vous coucher, et la section suivante est plus profonde
Il se fait tard, donc je finirai par écrire aujourd'hui. Jusqu'à présent, tout le monde peut proposer l'extension Hello World C ++ la plus élémentaire. La prochaine fois que je l'écrirai, je ne sais pas quand la prochaine fois sera.
(Hé, hé, comment le maître peut-il être si irresponsable! (O ゚ロ?) ┌┛σ (ノ ´ω`) ノ