Überarbeiten Sie das Alte und lernen Sie das Neue, Sie können nass werden
Denken Sie zunächst an dieses Online -Handbuch von V8 - http://izs.me/v8-docs/main.html.
Erinnern Sie sich an die letzte bauen.gyp -Datei?
Die Codekopie lautet wie folgt:
{
"Ziele": [
{
"target_name": "addon",
"Quellen": ["Addon.cc"]
}
]
}
Lernen Sie genau so aus einem Beispiel und lernen Sie daraus. Wenn Sie mehr *.cc -Dateien haben, wird dies so sein:
"Quellen": ["addon.cc", "myexample.cc"]
Das letzte Mal haben wir die beiden Schritte getrennt, und tatsächlich können Konfiguration und Zusammenstellung zusammengestellt werden:
$ node-gyp-bauen konfigurieren
Haben Sie die Überprüfung beendet? ohne? !
Ok, dann lass uns weitermachen.
Inhaltsverzeichnis
Funktionsparameter
Jetzt werden wir endlich über Parameter sprechen.
Stellen wir uns vor, es gibt eine Funktion hinzufügen (a, b), die das Hinzufügen von A und B darstellt, um das Ergebnis zurückzugeben. Schreiben Sie also zuerst den äußeren Rahmen: den äußeren Rahmen:
Die Codekopie lautet wie folgt:
#include <node.h>
Verwenden von Namespace V8;
Handle <wert> add (const argumente & args)
{
Handles -Scope;
// ... komm wieder!
}
Argumente
Dies ist der Parameter der Funktion. Schauen wir uns zuerst die offizielle manuelle Referenz von V8 an.
• int länge () const
• Lokal <wert> Operator [] (int i) const
Die anderen interessieren uns nicht, diese beiden sind sehr wichtig! Einer repräsentiert die Anzahl der in der Funktion übergebenen Parameter, und der andere sind die Klammern, die über den Indexindex auf den N -ten Parameter zugreifen.
Was die oben genannten Anforderungen betrifft, können wir grob verstehen, dass Args.Length () 2 ist, Args [0] repräsentiert a und args [1] b. Und wir müssen beurteilen, dass die Art dieser beiden Zahlen eine Nummer sein muss.
Nicht sicher, der Indexbetreiber in der Klammer gibt das Ergebnis eines lokalen <Wert> zurück, bei dem die Basisklasse aller Arten von Node.js. Wenn die eingegebenen Parameter von unterschiedlichem Typ sind, müssen wir daher beurteilen, welche Parameter es sind. Dies hängt mit einigen Funktionen dieses Werttyps zusammen.
• isarray ()
• isboolean ()
• isdate ()
• isFunction ()
• ISINT32 ()
• isnativeError ()
• iSnull ()
• isNumber ()
• isRegexp ()
• isstring ()
• ...
Ich werde sie nicht alle auflisten, den Rest alleine lesen. 。:. ゚ (*´∀`) ノ゚.:。
ThrowException
Dies ist eine Funktion, die wir später verwenden werden. Insbesondere kann es in der V8 -Dokumentation gefunden werden.
Wie der Name schon sagt, wirft er einen Fehler. Nach der Ausführung dieser Anweisung ist es gleichwertig mit der Ausführung einer Throw () -Antage in der lokalen Node.js -Datei. Zum Beispiel:
ThrowException (Ausnahme :: TypeError (String :: New ("Falsche Anzahl von Argumenten"));
Es entspricht der Ausführung eines Node.js:
Neue TypeRror werfen ("Falsche Anzahl von Argumenten");
Undefiniert()
Diese Funktion befindet sich auch im Dokument.
Insbesondere ist es ein Nullwert, da einige Funktionen keinen bestimmten Wert zurückgeben oder keinen Wert zurückgeben. Zu diesem Zeitpunkt muss undefined () stattdessen verwendet werden.
Maßnahmen ergreifen!
Nachdem Sie die oben genannten Punkte verstanden haben, können Sie bald die Logik von A + B schreiben. Ich werde den Code des offiziellen Handbuchs von Node.js kopieren und für Sie lesen. Es wird gemacht:
Die Codekopie lautet wie folgt:
#include <node.h>
Verwenden von Namespace V8;
Handle <wert> add (const argumente & args)
{
Handles -Scope;
// es bedeutet, dass mehr als 2 Parameter übergeben werden können, aber tatsächlich verwenden wir nur die ersten beiden
if (args.length () <2)
{
// einen Fehler werfen
ThrowException (Ausnahme :: TypeError (String :: New ("Falsche Anzahl von Argumenten"));
// leere Wert zurückgeben
return scope.close (undefined ());
}
// Wenn einer der ersten beiden Parameter keine Zahl ist
if (! args [0]-> isNumber () ||! args [1]-> isNumber ())
{
// einen Fehler werfen und einen Nullwert zurückgeben
ThrowException (Ausnahme :: TypeError (String :: New ("falsche Argumente"));
return scope.close (undefined ());
}
// Weitere Informationen finden Sie unter V8 -Dokumentation
// http://izs.me/v8-docs/classv8_1_1value.html#a6eAC2B07DCED58F1761BBFD53BF0E36)
// `numberValue` -Funktion
Lokale <Nummer> num = number :: new (args [0]-> numberValue () + args [1]-> numberValue ());
return scope.close (num);
}
Die Funktion ist erledigt!
Schreiben Sie schließlich die Exportfunktion am Ende und es wird in Ordnung sein.
Die Codekopie lautet wie folgt:
void init (Handel <objekt> Exporte)
{
Exporte-> set (String :: Newsymbol ("Add"),
FunctionTemplate :: new (hinzufügen)-> getFunction ());
}
Node_module (addon, init)
Nachdem Sie kompiliert haben, können wir es so verwenden:
Die Codekopie lautet wie folgt: var addon = required ('./ Build/Release/Addon');
console.log (addon.add (1, 1) + "b");
Sie werden eine 2B sehen! ✧。٩ (ᗜ) و✧*.
Rückruffunktion
Im vorherigen Kapitel haben wir nur über Hello World gesprochen. In diesem Kapitel entdeckte der Oma -Meister es mit Gewissen und schrieb eine Rückruffunktion.
Lassen Sie uns zuerst einen Framework schreiben:
Die Codekopie lautet wie folgt:
#include <node.h>
Verwenden von Namespace V8;
Handle <wert> runcallback (const argumente & args)
{
Handles -Scope;
// ... cracky crackle knistern knistern knistknist knistknistknist
return scope.close (undefined ());
}
Dann entscheiden wir, wie es so verwendet wird:
func (Funktion (msg) {
console.log (msg);
});
Das heißt, es wird einen Parameter an die Rückruffunktion übergeben, wir stellen uns vor, es ist eine Zeichenfolge, und dann können wir konsolen.log (), um sie zu sehen.
Zuerst brauchen Sie eine String -Serie
Lassen Sie uns zuerst eine Zeichenfolge füttern. (√ ζ ε :)
Aber wir müssen diese Zeichenfolge von generischen Typen erstellen, da der Node.js -Code schwach ist.
Lokal <Warts> :: New (String :: New ("Hallo Welt"));
Was? Sie fragen mich, was lokal <wert>?
Dann werde ich ein wenig darüber sprechen, mich auf die Referenzdokumente von hier und V8 beziehen.
Wie die Dokumentation zeigt, erbt lokales <t> tatsächlich von Handle <t>, und ich erinnere mich, dass das vorherige Kapitel bereits über Handle <t> gesprochen hatte.
Dann ist hier der Einheimische.
Es gibt zwei Arten von Griffen, lokalem Griff und anhaltendem Griff, die lokale <t>: Handle <T> und persistentes <t>: Handle <t> sind. Es gibt keinen Unterschied zwischen den ersteren und Handlungen <T> und beide Überlebenszyklen befinden sich im Bereich. Der Lebenszyklus des letzteren ist vom Zielfernrohr getrennt. Sie müssen manuell persistent bezeichnen :: Entsetzt, um seinen Lebenszyklus zu beenden. Mit anderen Worten, der lokale Griff entspricht der Zuweisung von Objekten auf dem Stapel auf C ++ - und persistentem Griff entspricht C ++, die Objekte auf dem Haufen zuweisen.
Dann benötigen Sie eine Parameter -Tabellenserie
Wie kann ich die Befehlszeilenparameter erhalten, nachdem Sie C/C ++ in der Terminal -Befehlszeile aufgerufen haben?
Die Codekopie lautet wie folgt:
#include <stdio.h>
void main (int argc, char* argv [])
{
// ...
}
Übrigens ist der Argc hier die Anzahl der Befehlszeilenparameter, und Argv [] sind die verschiedenen Parameter. Dann verwendet V8 auch eine ähnliche Methode, um Node.js 'Rückruffunktion aufzurufen:
Die Codekopie lautet wie folgt: v8export lokal <wert> v8 :: function :: call (Handle <object> recv,
int argc,
Verarbeiten <wert> argv []
);
~~ QAQ steckt im Handel <objekt> recv fest! ! ! Schreiben Sie morgen weiter. ~~
Nun, der neue Tag beginnt und ich fühle mich voller Stärke. (∩^o^) ⊃━☆゚.*・。。
Nachdem ich in vielen Aspekten (Segmentfault, Stackoverflow und einer QQ -Gruppe) überprüft habe, löste ich schließlich die Bedeutung der drei Parameter der obigen Funktion.
Ich werde nicht über die letzten beiden Parameter sprechen, eine ist die Anzahl der Parameter, und das andere ist ein Array von Parametern. Wie für die erste Parameter -Handle < -Objekt> recv ist die Erklärung des Stackoverflow -Bruders wie folgt:
Es ist dasselbe wie in JS angewandt. In JS tun Sie
Die Codekopie lautet wie folgt:
var context = ...;
CB.Apply (Kontext, [... Args ...]);
Das als erste Argument übergebene Objekt wird innerhalb des Funktionsbereichs zu dies. Weitere Dokumentation zu MDN. Wenn Sie JS nicht gut kennen, können Sie hier mehr über JS's This lesen: http://unschooled.org/2012/03/und verstanden-javascript-this/
- Ausgeklagte aus Stackoverflow
Kurz gesagt, seine Funktion besteht darin, diesen Zeiger auf die aufgerufene Funktion anzugeben. Die Verwendung dieses Anrufs ähnelt Bind (), call () und anwenden () in JavaScript.
Wir müssen also zuerst die Parametertabelle erstellen und dann diese Anruffunktion für ihre Ausführung übergeben.
Der erste Schritt besteht darin, die Konvertierungsfunktion anzuzeigen, da sie ursprünglich ein Objekttyp war:
Lokal <funktion> cb = lokal <funktion> :: cast (args [0]);
Der zweite Schritt besteht darin, eine Parametertabelle (Array) zu erstellen:
Lokal <Werts> argv [argc] = {lokal <wert> :: new (string :: new ("Hallo Welt")};
Der letzte Anruf der Funktionserie
Rufen Sie CB an und übergeben Sie die Parameter in:
cb-> call (context :: getCurrent ()-> global (), 1, argv);
Der erste Parameter hier Kontext :: getCurrent ()-> global () bedeutet, diese Funktion des globalen Kontextes zu erhalten. Der zweite Parameter ist die Zahl in der Parametertabelle (doch, obwohl das Array von Node.js ein Längenattribut hat, kennt das System tatsächlich nicht die Länge des Arrays in C ++, und Sie müssen in einer Zahl übergeben, um die Länge des Arrays zu erklären). Der letzte Parameter ist die gerade festgelegte Parametertabelle.
Letzte Kapitelenddateiserie
Ich glaube, dass alle mit diesem Schritt bereits vertraut sind, einfach die Funktion schreiben, dann in die Exportfunktion einfügen und schließlich deklarieren.
Ich werde einfach den Code posten oder einfach zum Dokument von Node.js gehen, um ihn zu lesen.
Die Codekopie lautet wie folgt:
#include <node.h>
Verwenden von Namespace V8;
Handle <wert> runcallback (const argumente & args)
{
Handles -Scope;
Lokal <funktion> cb = lokal <funktion> :: cast (args [0]);
const unsigned argc = 1;
Lokal <Werts> argv [argc] = {lokal <wert> :: new (string :: new ("Hallo Welt")};
cb-> call (context :: getCurrent ()-> global (), argc, argv);
return scope.close (undefined ());
}
void init (Handel <objekt> Exportieren, Handelungsmodul)
{
Modul-> set (String :: Newsymbol ("Exporte"),
FunctionTemplate :: new (runcallback)-> getfunction ());
}
Node_module (addon, init)
Gut gemacht! Lass uns die letzten Schritte selbst gehen. Wenn ich diese Funktion in JS aufzurufen habe, habe ich sie schon einmal erwähnt.
Extra
Nun, ich habe das Gefühl, dass meine Studiennotizen immer uneingeschränkter werden und sie brechen wollen ~
Lass uns heute hier aufhören. Während des Schreibens von Studiennotizen habe ich meine Haltung erneut erhöht, wie z. B. die Parameterbedeutung der Anruffunktion.
Wenn Sie der Meinung sind, dass diese Reihe von Studiennotizen für Sie hilfreich ist, kommen Sie und haben Sie eine gute Zeit mit mir ~ σ> (〃 ° ω ° ° 〃) ♡ →