Ein vor langer Zeit aufgetretener Fallstrick – die Verwendung von Node.js zur Rekonstruktion des Online-Richters von NBUT, einschließlich der Bewertungsseite, musste ebenfalls rekonstruiert werden. (Machen Sie sich keine Sorgen darüber, wann es abgeschlossen sein wird, (/‵Д′)/~ ╧╧
Kurz gesagt, was wir jetzt tun müssen, ist tatsächlich C/C zu verwenden, um das Node.js-Modul zu implementieren.
Vorbereitung
Wenn ein Arbeiter seine Arbeit gut machen will, muss er zuerst ~~einen Schurken spielen~~ und seine Werkzeuge schärfen.
node-gyp
Zuerst benötigen Sie ein Node-Gyp-Modul.
Führen Sie an einer beliebigen Ecke Folgendes aus:
Nach einer Reihe von Blablas sind Sie installiert.
Python
Dann benötigen Sie eine Python-Umgebung.
Gehen Sie auf die offizielle Website, um sich selbst eins zu besorgen.
Hinweis: Laut GitHub von node-gyp stellen Sie bitte sicher, dass Ihre Python-Version zwischen 2.5.0 und 3.0.0 liegt.
Kompilierungsumgebung
Nun, ich bin einfach zu faul, es im Detail aufzuschreiben. Bitte gehen Sie zu Node-Gyp, um die Compiler-Anforderungen zu sehen. Und gut einschenken.
Erste Schritte
Lassen Sie mich kurz auf die Einführung „Hello World“ auf der offiziellen Website eingehen.
Hallo Welt
Bitte bereiten Sie eine C-Datei vor, nennen Sie sie beispielsweise ~~sb.cc~~ hello.cc.
Dann gehen wir Schritt für Schritt vor, erstellen zunächst die Header-Datei und definieren den Namespace:
Hauptfunktion
Als nächstes schreiben wir eine Funktion, deren Rückgabewert Handle
Dann lassen Sie mich diese Dinge kurz analysieren:
Handle
Man muss als Mensch Integrität haben. Ich möchte vorab sagen, dass ich mich hierauf beziehe (@fool).
V8 verwendet den Handle-Typ zum Hosten von JavaScript-Objekten. Ähnlich wie bei Cs std::sharedpointer übergeben Zuweisungen zwischen Handle-Typen Objektreferenzen direkt. Der Unterschied besteht jedoch darin, dass V8 einen eigenen GC verwendet, um den Objektlebenszyklus zu verwalten, und nicht intelligente, häufig verwendete Referenzen Zählen für Zeiger.
JavaScript-Typen verfügen in C über entsprechende benutzerdefinierte Typen wie String, Integer, Object, Date, Array usw., die sich strikt an die Vererbungsbeziehung in JavaScript halten. Wenn Sie diese Typen in C verwenden, müssen Sie die Handle-Verwaltung verwenden, um den GC zur Verwaltung ihres Lebenszyklus zu verwenden, anstatt den nativen Stack und Heap zu verwenden.
Dieser sogenannte Wert ist aus den verschiedenen Vererbungsbeziehungen in der Header-Datei v8.h der V8-Engine ersichtlich. Es handelt sich tatsächlich um die Basisklasse verschiedener Objekte in JavaScript.
Nachdem wir dies verstanden haben, können wir die Bedeutung der obigen Funktionsdeklaration grob verstehen, nämlich dass wir eine Hello-Funktion schreiben, die einen unbestimmten Typwert zurückgibt.
Hinweis: Unter der Handle-Verwaltung können wir nur bestimmte Typen zurückgeben, nämlich String, Integer usw.
Argumente
Dies ist der Parameter, der an diese Funktion übergeben wird. Wir alle wissen, dass in Node.js die Anzahl der Parameter zufällig ist. Wenn diese Parameter an C übergeben werden, werden sie in Objekte dieses Argumenttyps konvertiert.
Wir werden später über die spezifische Verwendung sprechen. Hier müssen Sie nur verstehen, was das ist. (Warum sind Sie so kritisch? Weil die Beispiele in der offiziellen Node.js-Dokumentation separat besprochen werden. Ich spreche jetzt nur vom ersten Hello World-Beispiel (´థ౪థ)σ
Beitrag
Dann begannen wir mit dem Hinzufügen von Ziegeln und Fliesen. Nur zwei einfache Sätze:
Was bedeuten diese beiden Sätze? Die grobe Bedeutung besteht darin, eine Zeichenfolge „world“ in Node.js zurückzugeben.
HandleScope
Der gleiche Hinweis stammt von hier.
Der Lebenszyklus von Handle unterscheidet sich von dem von C-Smart-Pointern. Er existiert nicht im Rahmen der C-Semantik (dh des von {} umgebenen Teils), sondern muss manuell über HandleScope angegeben werden. HandleScope kann nur auf dem Stapel zugewiesen werden, nachdem das HandleScope-Objekt deklariert wurde. Der Lebenszyklus des anschließend erstellten Handles wird von HandleScope verwaltet. Nach der Zerstörung des HandleScope-Objekts wird vom GC beurteilt, ob dies der Fall ist recycelt.
Wir müssen diesen Bereich also deklarieren, wenn wir seinen Lebenszyklus verwalten müssen. Okay, warum sieht unser Code nicht so aus?
Denn wenn die Funktion zurückkehrt, wird der Bereich zerstört und die von ihr verwalteten Handles werden ebenfalls recycelt, sodass dieser String bedeutungslos wird.
Also hatte V8 eine magische Idee – die Funktion HandleScope::Close(Handle
Da ist also unser bisheriger Code-Bereich.Close(String::New("world"));.
String::New
Diese String-Klasse entspricht der nativen String-Klasse in Node.js. Von der Value-Klasse geerbt. Ähnlich gibt es auch:
•Array
•Ganzzahl
•Boolean
•Objekt
•Datum
•Nummer
•Funktion
•...
Einige dieser Dinge werden von Value geerbt, andere werden doppelt geerbt. Wir werden hier nicht viel recherchieren. Sie können sich den V8-Code (zumindest die Header-Dateien) ansehen oder dieses Handbuch lesen.
Und was ist mit diesem Neuen? Sie können es hier sehen. Erstellen Sie einfach ein neues String-Objekt.
An diesem Punkt haben wir die Analyse dieser Hauptfunktion abgeschlossen.
Objekt exportieren
Sehen wir uns das noch einmal an. Wie exportieren wir Funktionen oder Objekte, wenn wir es in Node.js schreiben?
Wie machen wir das also in C?
Initialisierungsfunktion
Zuerst schreiben wir eine Initialisierungsfunktion:
Das ist der Schildkröten-Hintern! Es spielt keine Rolle, wie der Funktionsname lautet, aber der übergebene Parameter muss ein Handle
Dann schreiben wir die exportierten Sachen hier:
Die allgemeine Bedeutung besteht darin, dass diesem Exportobjekt ein Feld namens „Hallo“ hinzugefügt wird und das entsprechende Ding eine Funktion ist, und diese Funktion ist unsere liebe Hallo-Funktion.
Um es einfach in Pseudocode auszudrücken:
Fertig!
(Es ist geschafft, Schwester! Halt die Klappe (‘д‘⊂彡☆))Д´)
True·Export
Dies ist der letzte Schritt. Wir müssen angeben, dass dies der Eingang zum Export ist, also fügen wir diese Zeile am Ende des Codes hinzu:
NODE_MODULE(Hallo, init)
Hast du einen Nenny bezahlt? ! Was ist das?
Keine Sorge, dieses NODE_MODULE ist ein Makro, was bedeutet, dass wir die zu exportierenden Dinge mit der Initialisierungsfunktion init nach Hallo exportieren. Woher kommt also dieses Hallo?
Es kommt vom Dateinamen! Ja, das stimmt, es kommt vom Dateinamen. Sie müssen es nicht im Voraus deklarieren und müssen sich keine Sorgen machen, dass Sie es nicht verwenden können. Kurz gesagt, wie auch immer der Name Ihrer endgültigen kompilierten Binärdatei lautet, geben Sie hier einfach das „Hallo“ ein, außer für das Suffix natürlich.
Einzelheiten finden Sie in der offiziellen Dokumentation.
Beachten Sie, dass alle Node-Add-ons eine Initialisierungsfunktion exportieren müssen:
Nach NODE_MODULE steht kein Semikolon, da es sich nicht um eine Funktion handelt (siehe node.h).
Der Modulname muss mit dem Dateinamen der endgültigen Binärdatei übereinstimmen (abzüglich des Suffixes .node).
Kompilieren (๑•́ ₃ •̀๑)
Komm, lass es uns gemeinsam zusammenstellen!
Erstellen wir eine neue Archivdatei ähnlich Makefile – binding.gyp.
Und fügen Sie diesen Code ein:
Warum schreibst du das so? Sie können sich auf die offizielle Dokumentation von Node-Gyp beziehen.
konfigurieren
Nachdem die Datei fertig ist, müssen wir diesen Befehl in diesem Verzeichnis ausführen:
Wenn alles normal ist, sollte ein Build-Verzeichnis generiert werden, in dem sich zugehörige Dateien befinden, möglicherweise die vcxproj-Datei von M$ Visual Studio usw., möglicherweise Makefile, je nach Plattform.
bauen
Nachdem das Makefile generiert wurde, beginnen wir mit dem Erstellen und Kompilieren:
$ node-gyp build
Wenn alles kompiliert ist, ist es wirklich fertig! Wenn Sie mir nicht glauben, schauen Sie sich das Build/Release-Verzeichnis an. Gibt es unten eine hello.node-Datei? Ja, das ist die Soap, die C später für Node.js abholen wird!
Werde schwul! Knoten ヽ(✿゚▽゚)ノ C
Wir erstellen gerade eine neue Datei jianfeizao.js im Verzeichnis:
Hast du es gesehen? Hast du es gesehen? Es ist raus, es ist raus! Das Ergebnis davon, dass Node.js und C radikal sind! Dieses addon.hello() ist das Handle
Geh schlafen, der nächste Abschnitt wird ausführlicher sein
Es ist schon spät, das ist also alles für heute. Jetzt kann jeder die einfachste C-Erweiterung von Hello World erstellen. Das nächste Mal, wenn ich schreibe, sollte es ausführlicher sein. Wann das nächste Mal sein wird, weiß ich eigentlich nicht.
(Hey, hey, hey, wie kann ein Masturbator so verantwortungslos sein! (o゚ロ゚)┌┛Σ(ノ´ω`)ノ