Un écueil survenu il y a longtemps : l'utilisation de Node.js pour reconstruire le juge en ligne de NBUT, y compris le côté évaluation, a également dû être reconstruite. (Quant à quand il sera terminé, ne vous inquiétez pas, (/‵Д′)/~ ╧╧
Bref, ce qu'il nous reste à faire maintenant, c'est effectivement d'utiliser C/C pour implémenter le module Node.js.
Préparation
Si un ouvrier veut bien faire son travail, il doit d'abord~~jouer au voyou~~ et affûter ses outils.
noeud-gyp
Vous avez d’abord besoin d’un module node-gyp.
Dans n'importe quel coin, exécutez :
Après une série de blabla, vous voilà installé.
Python
Ensuite, vous avez besoin d'un environnement python.
Rendez-vous sur le site officiel pour vous en procurer un vous-même.
Remarque : selon le GitHub de node-gyp, veuillez vous assurer que votre version de Python est comprise entre 2.5.0 et 3.0.0.
Environnement de compilation
Eh bien, je suis tout simplement trop paresseux pour l'écrire en détail. Veuillez vous rendre sur node-gyp pour voir les exigences du compilateur. Et versez-le bien.
Démarrage
Permettez-moi juste de parler de l'introduction de Hello World sur le site officiel.
Bonjour tout le monde
Veuillez préparer un fichier C, par exemple, appelez-le ~~sb.cc~~ hello.cc.
Ensuite, allons-y étape par étape, créez d'abord le fichier d'en-tête et définissez l'espace de noms :
Fonction principale
Ensuite, nous écrivons une fonction dont la valeur de retour est Handle
Alors laissez-moi analyser brièvement ces choses :
Poignée
Vous devez être intègre en tant qu'être humain. Je tiens à préciser par avance que j'y fais référence à partir d'ici (@fool).
La V8 utilise le type Handle pour héberger les objets JavaScript. Semblable au std::sharedpointer de C, les affectations entre les types Handle transmettent directement les références d'objet, mais la différence est que la V8 utilise son propre GC pour gérer le cycle de vie des objets, plutôt qu'une référence intelligente couramment utilisée. compter pour les pointeurs.
Les types JavaScript ont des types personnalisés correspondants en C, tels que String, Integer, Object, Date, Array, etc., qui respectent strictement la relation d'héritage en JavaScript. Lorsque vous utilisez ces types en C, vous devez utiliser la gestion des handles pour utiliser le GC afin de gérer leur cycle de vie au lieu d'utiliser la pile et le tas natifs.
Cette soi-disant valeur peut être vue à partir des différentes relations d'héritage dans le fichier d'en-tête v8.h du moteur V8. Il s'agit en fait de la classe de base de divers objets en JavaScript.
Après avoir compris cela, nous pouvons à peu près comprendre la signification de la déclaration de fonction ci-dessus, c'est-à-dire que nous écrivons une fonction Hello qui renvoie une valeur de type indéfinie.
Remarque : Nous ne pouvons renvoyer que des types spécifiques, à savoir String, Integer, etc. sous Gestion des handles.
Arguments
C'est le paramètre passé 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 objets de ce type Arguments.
Nous parlerons de l'utilisation spécifique plus tard, ici il vous suffit de comprendre de quoi il s'agit. (Pourquoi êtes-vous si critique ? Parce que les exemples de la documentation officielle de Node.js sont discutés séparément. Je parle juste du premier exemple de Hello World maintenant (´థ౪థ)σ
Contribution
Ensuite, nous avons commencé à ajouter des briques et des tuiles. Juste deux phrases simples :
Que signifient ces deux phrases ? Le sens approximatif est de renvoyer une chaîne « monde » dans Node.js.
HandleScope
La même référence vient d'ici.
Le cycle de vie de Handle est différent de celui des pointeurs intelligents C. Il n'existe 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é, le cycle de vie du Handle créé par la suite est géré par HandleScope. Après la destruction de l'objet HandleScope, le Handle géré par celui-ci sera jugé par le GC s'il doit l'être. recyclé.
Nous devons donc déclarer ce Scope lorsque nous devons gérer son cycle de vie. D'accord, alors pourquoi notre code ne ressemble-t-il pas à ceci ?
Parce que lorsque la fonction reviendra, la portée sera détruite et les Handles qu'elle gère seront également recyclés, donc cette String n'aura plus de sens.
Le V8 a donc eu une idée magique : la fonction HandleScope::Close(Handle
Il y a donc notre précédent code scope.Close(String::New("world"));.
Chaîne ::Nouveau
Cette classe String correspond à la classe string native dans Node.js. Hérité de la classe Value. Semblable à ceci, il y a aussi :
•Tableau
•Entier
•Booléen
•Objet
•Date
•Numéro
•Fonction
•...
Certaines de ces choses sont héritées de Value, et d’autres sont héritées deux fois. Nous ne ferons pas beaucoup de recherches ici. Vous pouvez consulter le code V8 (au moins les fichiers d'en-tête) ou lire ce manuel.
Et que dire de cette Nouveauté ? Vous pouvez le voir ici. Créez simplement un nouvel objet String.
À ce stade, nous avons terminé l'analyse de cette fonction principale.
Exporter l'objet
Passons en revue. Si nous l'écrivons en Node.js, comment exporter des fonctions ou des objets ?
Alors, comment fait-on cela en C ?
Fonction d'initialisation
Tout d'abord, nous écrivons une fonction d'initialisation :
C'est le cul de tortue ! Le nom de la fonction n'a pas d'importance, mais le paramètre transmis doit être un Handle
Ensuite, nous écrivons ici les éléments exportés :
Le sens général est que, ajoutez un champ appelé bonjour à cet objet d'exportation, et la chose correspondante est une fonction, et cette fonction est notre chère fonction Bonjour.
Pour le dire clairement en pseudo code :
C'est fait !
(C'est fait, sœur ! Tais-toi ('д‘⊂彡☆))Д´)
Vrai·Exporter
C'est la dernière étape. Il faut déclarer que c'est l'entrée à l'export, on ajoute donc cette ligne à la fin du code :
NODE_MODULE(bonjour, init)
Avez-vous payé une nenny ? ! 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 init pour exporter les éléments à exporter vers hello. Alors d'où vient ce bonjour ?
Cela vient du nom du fichier ! Oui, c'est vrai, cela vient du nom du fichier. Vous n'avez pas besoin de le déclarer à l'avance, et vous n'avez pas à craindre de ne pas pouvoir l'utiliser. Bref, quel que soit le nom de votre fichier binaire compilé final, remplissez simplement le bonjour ici, sauf pour. le suffixe bien sûr.
Consultez la documentation officielle pour plus de détails.
Notez que tous les addons Node doivent exporter une fonction d'initialisation :
Il n'y a pas de point-virgule après NODE_MODULE car ce n'est pas une fonction (voir node.h).
Le nom_module doit correspondre au nom de fichier du binaire final (moins le suffixe .node).
Compiler (๑•́ ₃ •̀๑)
Allez, compilons-le ensemble !
Créons un nouveau fichier d'archive similaire à Makefile - bind.gyp.
Et ajoutez ce code à l'intérieur :
Pourquoi tu l'écris comme ça ? 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 :
Si tout est normal, un répertoire de construction doit être généré, et il contiendra des fichiers associés, peut-être le fichier vcxproj de M$ Visual Studio, etc., peut-être Makefile, selon la plateforme.
construire
Une fois le Makefile généré, nous commençons à construire et à compiler :
$ build nœud-gyp
Quand tout est compilé, c'est vraiment fait ! Si vous ne me croyez pas, jetez un œil au répertoire build/Release. Y a-t-il un fichier hello.node ci-dessous ? Oui, c'est le savon que C récupérera pour Node.js plus tard !
Devenez gay ! Nœud ヽ(✿゚▽゚)ノ C
Nous créons tout à l'heure un nouveau fichier jianfeizao.js dans le répertoire :
Vous l'avez vu ? L'avez-vous vu ? C'est sorti, c'est sorti ! Le résultat de la radicalité de Node.js et C ! Cet addon.hello() est le Handle
Allez dormir, la prochaine section sera plus approfondie
Il se fait tard, c'est donc tout pour aujourd'hui. Tout le monde peut désormais créer l'extension C la plus basique de Hello world. La prochaine fois que j’écrirai, je devrais être plus approfondi. Quant à savoir quand aura lieu la prochaine fois, en fait, je ne le sais pas.
(Hé, hé, hé, comment un masturbateur peut-il être si irresponsable ! (o゚ロ゚)┌┛Σ(ノ´ω`)ノ