Eine Gefahr von N vor langer Zeit - mit Node.js zum Rekonstruktion von NBUTs Online -Richter, einschließlich der Bewertungsseite, muss ebenfalls rekonstruiert werden. (Wenn es abgeschlossen ist, ist es egal, (/д ')/~
Kurz gesagt, wir werden jetzt C/C ++ verwenden, um Node.js -Module zu implementieren.
Vorbereitung
Wenn Sie die Dinge gut machen möchten, müssen Sie zuerst wie ein Gangster handeln und Ihre Werkzeuge schärfen.
Knotengyp
Zuerst benötigen Sie ein Knoten-GYP-Modul.
In jeder Ecke ausführen:
Die Codekopie lautet wie folgt:
$ npm install node -gyp -g
Nach einer Reihe von Blahblahs haben Sie es installiert.
Python
Dann müssen Sie eine Python -Umgebung haben.
Gehen Sie zur offiziellen Website und holen Sie sich eine.
HINWEIS: Stellen Sie nach der Github-Anzeige von Node-GYP sicher, dass Ihre Python-Version zwischen 2.5.0 und 3.0.0 liegt.
Kompilierungsumgebung
Nun, ich bin nur faul und schreibe es nicht im Detail. Bitte wechseln Sie zu Node-GYP, um die Bedürfnisse des Compilers zu sehen. Und eine Aufregung machen.
Erste Schritte
Ich werde Ihnen von der Einführung in die offizielle Website Hello World erzählen.
Hallo Welt
Bitte bereiten Sie eine C ++ - Datei vor, beispielsweise heißt ~~ SB.cc ~~ Hallo.cc.
Dann werden wir einen Schritt für Schritt machen, zuerst die Header -Datei erstellen und den Namespace definieren:
Die Codekopie lautet wie folgt:
#include <node.h>
#include <v8.h>
Verwenden von Namespace V8;
Hauptfunktionen
Als nächstes schreiben wir eine Funktion, deren Rückgabewert Handle <wert> ist.
Die Codekopie lautet wie folgt:
Handle <wert> Hallo (const argumente & args)
{
// ... war hungrig, geschrieben zu werden
}
Dann werde ich diese Dinge grob analysieren:
Handle <wert>
Sie müssen im Leben ehrlich sein. Ich erkläre im Voraus, dass ich es von hier an (@Fool) beziehe.
V8 verwendet den Handy -Typ, um JavaScript -Objekte zu hosten. Ähnlich wie bei C ++ von STD :: SharedPointer werden die Zuordnungen zwischen den Handy -Typen direkt übergeben. Objektreferenzen. Der Unterschied besteht jedoch darin, dass V8 seinen eigenen GC verwendet, um den Objektlebenszyklus zu verwalten, und nicht die Referenzzahl, die von intelligenten Zeigern üblicherweise verwendet wird.
JavaScript -Typen haben entsprechende benutzerdefinierte Typen in C ++, z. B. String, Ganzzahl, Objekt, Datum, Array usw. und halten sich streng an die Vererbungsbeziehung in JavaScript. Wenn Sie diese Typen in C ++ verwenden, müssen Sie das Handle -Hosting verwenden, um GC zu verwenden, um ihre Lebenszyklen zu verwalten, ohne native Stapel und Haufen zu verwenden.
Dieser sogenannte Wert, der aus den verschiedenen Vererbungsbeziehungen in der Header-Datei v8.h der V8-Engine ersichtlich ist, ist tatsächlich die Grundklasse verschiedener Objekte in JavaScript.
Nachdem wir dies verstanden haben, können wir die Bedeutung der obigen Funktionserklärung grob verstehen, was bedeutet, dass wir eine Hallo -Funktion schreiben, die einen Wert eines unsicheren Typs zurückgibt.
Hinweis: Wir können nur bestimmte Typen zurückgeben, nämlich String, Ganzzahl usw. unter dem Handle Hosting.
Argumente
Dies ist der Parameter, der in dieser Funktion übergeben wird. Wir alle wissen, dass in Node.js die Anzahl der Parameter zufällig ist. Wenn diese Parameter in C ++ übergeben werden, werden sie in ein Argumente -Typ -Objekt konvertiert.
Lassen Sie uns später über die spezifische Nutzung sprechen. Hier müssen wir nur verstehen, was das ist. (Um es geheim zu halten? Weil die Beispiele im offiziellen Knoten.JS -Dokument separat besprochen werden. Ich spreche nur über das erste Hello World -Beispiel (´థ౪థ) σ
Fügen Sie Ziegel und Fliesen hinzu
Als nächstes beginnen wir beizutragen. Nur die einfachsten Sätze:
Die Codekopie lautet wie folgt:
Handle <wert> Hallo (const argumente & args)
{
Handles -Scope;
Return Scope.close (String :: New ("Welt"));
}
Was bedeuten diese beiden Sätze? Die allgemeine Bedeutung ist, eine Zeichenfolge "Welt" in Node.js. zurückzugeben.
HandlesCope
Die gleiche Referenz stammt von hier.
Der Lebenszyklus des Griffs unterscheidet sich von dem von C ++ - intelligenten Zeigern. Es überlebt nicht im Rahmen der C ++ - Semantik (dh dem von {}) umgebenen Teil, sondern muss manuell durch HandlesCope angegeben werden. HandlesCope kann nur auf dem Stapel zugewiesen werden. Nachdem das HandleScope -Objekt deklariert wurde, wird der später erstellte Griff von HandlesCope verwaltet. Nachdem das HandleScope -Objekt zerstört wurde, wird der von ihm verwaltete Griff vom GC bestimmt.
Wir müssen diesen Umfang erklären, wenn wir seinen Lebenszyklus verwalten müssen. OK, warum wird unser Code nicht so geschrieben?
Die Codekopie lautet wie folgt:
Handle <wert> Hallo (const argumente & args)
{
Handles -Scope;
Return String :: New ("Welt");
}
Denn wenn die Funktion zurückkehrt, wird der Umfang zerstört und die Handles, die sie verwaltet, wird recycelt, sodass diese Zeichenfolge bedeutungslos wird.
So kam V8 eine magische Idee - die HandlesCope :: Close (Handle <T> Wert) Funktion! Der Zweck dieser Funktion ist es, den Umfang zu schließen und die Parameter im Inneren der vorherigen Umfangsmanagement zu übergeben, dh den Umfang vor dem Eintritt in diese Funktion.
Wir haben also den vorherigen Code Scope.close (String :: New ("Welt");.
String :: Neu
Die String -Klasse entspricht der nationalen String -Klasse in node.js. Aus der Wertklasse geerbt. Ebenso gibt es:
• Array
•Ganze Zahl
• boolean
•Objekt
•Datum
•Nummer
•Funktion
• ...
Einige dieser Dinge werden vom Wert geerbt, während andere von Sekundärer geerbt werden. Wir werden hier nicht viel recherchieren. Sie können sich den V8 -Code (zumindest die Header -Datei) ansehen oder dieses Handbuch ansehen.
Und was ist mit diesem neuen? Sie können es hier sehen. Es soll ein neues String -Objekt erstellen.
Zu diesem Zeitpunkt haben wir diese Hauptfunktion analysiert.
Objekte exportieren
Lassen Sie es uns überprüfen. Wenn es in node.js geschrieben ist, wie exportieren wir Funktionen oder Objekte?
Die Codekopie lautet wie folgt:
exports.hello = function () {}
Wie können wir das in C ++ tun?
Funktion initialisieren
Lassen Sie uns zunächst eine Initialisierungsfunktion schreiben:
Die Codekopie lautet wie folgt:
void init (Handel <objekt> Exporte)
{
// ... Ich bin hungrig, über deine Schwester zu schreiben! #゚ Å ゚) ⊂ち☆)) ゚ д ゚) ・∵
}
Dies ist ein Schildkrötenarsch! Es spielt keine Rolle, ob der Funktionsname oder etwas, aber der übergebene Parameter ein Handle <objekt> sein muss, was bedeutet, dass wir Dinge aus diesem Produkt unten exportieren.
Dann schreiben wir das exportierte Ding hier:
Die Codekopie lautet wie folgt:
void init (Handel <objekt> Exporte)
{
Exporte-> set (String :: Newsymbol ("Hallo"),
FunctionTemplate :: new (Hallo)-> getFunction ());
}
Die allgemeine Bedeutung ist, ein Feld namens Hello zu diesem Exportobjekt hinzuzufügen, und die entsprechende Sache ist eine Funktion, und diese Funktion ist unsere liebe Hello -Funktion.
Um einen einfachen Punkt in Pseudo-Code zu schreiben:
Die Codekopie lautet wie folgt:
void init (Handel <objekt> Exporte)
{
exports.set ("Hallo", Funktion Hallo);
}
Die Arbeit ist erledigt!
(Deine Schwester ist fertig! Halt die Klappe ('д'⊂☡☆)) д´)
Wahrer Export
Dies ist der letzte Schritt, und wir werden endlich erklären, dass dies der Eingang zum Export ist. Daher fügen wir diese Zeile am Ende des Codes hinzu:
Node_module (Hallo, init)
Hast du einen Ni genommen? ! Was ist das?
Machen Sie sich keine Sorgen, dieses NODE_MODULE ist ein Makro, was bedeutet, dass wir die Initialisierungsfunktion verwenden, um die Dinge zu exportieren, die in Hello exportiert werden sollen. Woher kommt das Hallo her?
Es kommt aus dem Dateinamen! Ja, ja, es stammt aus dem Dateinamen. Sie müssen es nicht im Voraus deklarieren, und Sie müssen sich keine Sorgen machen, dass Sie es nicht benutzen können. Kurz gesagt, wie heißt Ihre endgültige kompilierte Binärdatei? Hier füllen Sie das Hallo aus und müssen natürlich den Suffixnamen entfernen.
Einzelheiten finden Sie in der offiziellen Dokumentation.
Beachten Sie, dass alle Knoten hinzugefügt werden müssen, um eine Initialisierungsfunktion zu exportieren:
Die Codekopie lautet wie folgt:
void initialize (Handel <objekt> Exporte);
Node_module (module_name, initialize)
Es gibt kein Halbkolon nach NODE_MODULE, da es sich nicht um eine Funktion handelt (siehe Node.h).
Der Modul_Name muss mit dem Dateinamen der endgültigen Binärdatei übereinstimmen (abzüglich des .node -Suffix).
Kompilieren (๑ • ́ ₃ • ̀๑)
Komm schon, lass uns zusammen kompilieren!
Erstellen wir eine neue Archivdatei ähnlich wie mit Makefile - binding.gyp.
Und fügen Sie den Code wie diesen hinzu:
Die Codekopie lautet wie folgt:
{
"Ziele": [
{
"target_name": "Hallo",
"Quellen": ["Hallo.cc"]
}
]
}
Warum das schreiben? Sie können sich auf die offizielle Dokumentation von Knotengypen beziehen.
konfigurieren
Nachdem die Datei fertig ist, müssen wir diesen Befehl in diesem Verzeichnis ausführen:
Die Codekopie lautet wie folgt:
$ node-gyp-Konfiguration
Wenn alles in Ordnung ist, sollte ein Build -Verzeichnis generiert werden, und dann gibt es je nach Plattform verwandte Dateien, möglicherweise m $ Visual Studio VCXProj -Datei usw. oder Makefile.
bauen
Nachdem das Makefile erzeugt wurde, beginnen wir zu konstruieren und zu kompilieren:
$ node-gyp Build
Nur wenn alles zusammengestellt wird, wird es angenommen, dass die eigentliche Aufgabe erledigt ist! Wenn Sie es nicht glauben, überprüfen Sie das Build/Release -Verzeichnis. Gibt es unten eine Hello.node -Datei? Das ist richtig, dies ist die Seife, die C ++ später für Node.js aufnehmen möchte!
Lassen Sie uns die Grundlagen bekommen! Knoten (✿゚゚) ノ C ++
Wir erstellen gerade jetzt eine neue Datei jianfeizao.js im Verzeichnis:
Die Codekopie lautet wie folgt:
var addon = required ("./ bauen/release/hello");
console.log (addon.hello ());
Sehen Sie es oder nicht! Sehen Sie es oder nicht! Herauskommen! Das Ergebnis von Node.js und C ++ erhalten Grundlagen! Dieser addon.hello () ist das Handle <wert> Hallo (const argumente & args), die wir zuvor in C ++ - Code geschrieben haben, und wir haben jetzt den von ihm zurückgegebenen Wert ausgegeben.
Duschen Sie und gehen Sie ins Bett, und der nächste Abschnitt ist tiefer
Es wird spät, also werde ich heute schreiben. Bisher kann jeder die grundlegendste Hello World C ++ - Erweiterung entwickeln. Wenn ich es das nächste Mal schreibe, weiß ich nicht, wann das nächste Mal sein wird.
(Hey, hey, wie kann der Meister so verantwortungslos sein! (O ゚ロ?) ┌┛σ (ノ ´ω`) ノ