Heim >Web-Frontend >js-Tutorial >Verwenden Sie C/C, um Node.js-Module (1)_node.js zu implementieren

Verwenden Sie C/C, um Node.js-Module (1)_node.js zu implementieren

WBOY
WBOYOriginal
2016-05-16 16:35:331231Durchsuche

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:

Code kopieren Der Code lautet wie folgt:

$ npm install node-gyp -g

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:

Code kopieren Der Code lautet wie folgt:

#include
#include
unter Verwendung des Namespace v8;

Hauptfunktion

Als nächstes schreiben wir eine Funktion, deren Rückgabewert Handle ist.

Code kopieren Der Code lautet wie folgt:

Handle Hello(const Arguments& args)
{
//... Warte darauf, geschrieben zu werden
}

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:

Code kopieren Der Code lautet wie folgt:

Handle Hello(const Arguments& args)
{
HandleScope-Bereich;
Gibt Scope.Close(String::New("world"));
zurück }

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?

Code kopieren Der Code lautet wie folgt:

Handle Hello(const Arguments& args)
{
HandleScope-Bereich;
Rückgabezeichenfolge::New("world");
}

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 Value)! Der Zweck dieser Funktion besteht darin, diesen Bereich zu schließen und die darin enthaltenen Parameter zur Verwaltung an den vorherigen Bereich zu übertragen, dh an den Bereich, bevor diese Funktion aufgerufen wird.

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?

Code kopieren Der Code lautet wie folgt:

exports.hello = function() {}

Wie machen wir das also in C?

Initialisierungsfunktion

Zuerst schreiben wir eine Initialisierungsfunktion:

Code kopieren Der Code lautet wie folgt:

void init(Handle exports)
{
//...ich warte darauf, über deine Schwester zu schreiben! #゚Å゚)⊂彡☆))゚Д゚)・∵
}

Das ist der Schildkröten-Hintern! Es spielt keine Rolle, wie der Funktionsname lautet, aber der übergebene Parameter muss ein Handle sein, was bedeutet, dass wir als nächstes etwas für dieses Produkt exportieren werden.

Dann schreiben wir die exportierten Sachen hier:

Code kopieren Der Code lautet wie folgt:

void init(Handle exports)
{
exports->Set(String::NewSymbol("hello"),
FunctionTemplate::New(Hello)->GetFunction());
}

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:

Code kopieren Der Code lautet wie folgt:

void init(Handle exports)
{
exports.Set("hello", Funktion hallo);
}

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:

Code kopieren Der Code lautet wie folgt:

void Initialize (Handle exports);
NODE_MODULE(Modulname, Initialisieren)

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:

Code kopieren Der Code lautet wie folgt:

{
„Ziele“: [
{
„target_name“: „Hallo“,
„Quellen“: [ „hello.cc“ ]
}
]
}

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:

Code kopieren Der Code lautet wie folgt:

$ node-gyp configure

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:

Code kopieren Der Code lautet wie folgt:

var addon = require("./build/Release/hello");
console.log(addon.hello());

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 Hello(const Arguments& args), das wir zuvor im C-Code geschrieben haben, und wir haben jetzt den zurückgegebenen Wert ausgegeben.

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゚ロ゚)┌┛Σ(ノ´ω`)ノ

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn