古いものを修正して新しいことを学ぶ、あなたは濡れることができます
まず第一に、v8 -http://izs.me/v8-docs/main.htmlのこのオンラインマニュアルを覚えておいてください。
最後のbuilding.gypファイルを覚えていますか?
コードコピーは次のとおりです。
{
「ターゲット」:[
{
"Target_name": "addon"、
「ソース」:["addon.cc"]
}
]
}
このように、一例から学び、それから学びます。あなたがもっと *.ccファイルを持っているなら、それは次のようになります:
「ソース」:["addon.cc"、 "myexample.cc"]]
前回2つのステップを分離しましたが、実際には、構成とコンパイルをまとめることができます。
$ node-gyp構成ビルド
レビューを終えましたか?それなし? !
さあ、続けましょう。
目次
関数パラメーター
今、私たちはついにパラメーターについて話します。
結果を返すためにaとbを追加することを表す関数add(a、b)があると想像してみましょう。
コードコピーは次のとおりです。
#include <node.h>
名前空間V8を使用。
<balue> add(const arguments&args)を処理する
{
ハンドルスコープスコープ。
// ...また来てください!
}
議論
これが関数のパラメーターです。最初にV8の公式マニュアルリファレンスを見てみましょう。
•int length()const
•local <value> operator [](int i)const
私たちは他の人を気にしません、これら2つは非常に重要です! 1つは関数で渡されるパラメーターの数を表し、もう1つはsubscriptインデックスを介してn番目のパラメーターにアクセスするブラケットです。
したがって、上記の要件については、args.length()が2であることを大まかに理解できます。そして、これらの2つの数値のタイプは数でなければならないと判断しなければなりません。
確かではありませんが、ブラケットのインデックス演算子は、ローカル<値>の結果を返します。これは、あらゆるタイプのnode.jsのベースクラスです。したがって、渡されたパラメーターがさまざまなタイプの場合、それがどのパラメーターであるかを判断する必要があります。これは、この値タイプのいくつかの関数に関連しています。
•isarray()
•iSboolean()
•isdate()
•IsFunction()
•ISINT32()
•isnativeerror()
•isnull()
•isNumber()
•isregexp()
•IssTring()
•...
私はそれらすべてをリストしません、残りを一人で読んでください。 。:。
ThrowException
これは後で使用する関数です。具体的には、V8ドキュメントに記載されています。
名前が示すように、エラーが発生しています。このステートメントを実行した後、ローカルnode.jsファイルでthro()ステートメントを実行することに相当します。例えば:
ThrowException(例外:: typeRror(string :: new( "誤った数の引数")));
node.jsの実行に相当します。
新しいTypeErrorを投げます( "誤った数の引数");
未定義()
この機能もドキュメントにあります。
具体的には、一部の関数は特定の値を返す必要がないか、値を返す必要がないため、ヌル値です。現時点では、代わりに未定義()を使用する必要があります。
行動を起こしてください!
上記の点を理解した後、私はあなたがすぐにA + Bの論理を書くことができると信じています。 node.jsの公式マニュアルのコードをコピーして、お読みください。それが行われます:
コードコピーは次のとおりです。
#include <node.h>
名前空間V8を使用。
<balue> add(const arguments&args)を処理する
{
ハンドルスコープスコープ。
//それは2つ以上のパラメーターを渡すことができることを意味しますが、実際には最初の2つのみを使用します
if(args.length()<2)
{
//エラーを投げます
ThrowException(例外:: typeRror(string :: new( "誤った数の引数")));
//空の値を返します
return scope.close(undefined());
}
//最初の2つのパラメーターのいずれかが数字ではない場合
if(!args [0] - > isNumber()||!args [1] - > isNumber())
{
//エラーを投げて、null値を返します
ThrowException(例外:: typeRror(string :: new( "誤った引数")));
return scope.close(undefined());
}
//詳細については、V8ドキュメントを参照してください
// http://izs.me/v8-docs/classv8_1_1value.html#a6eac2b07dced58f1761bbfd53bf0e366)
// `numberValue`関数
local <number> num = number :: new(args [0] - > numberValue() + args [1] - > numberValue());
return scope.close(num);
}
機能が完了しました!
最後に、最後にエクスポート機能を記述すると、問題ありません。
コードコピーは次のとおりです。
void init(ハンドル<オブジェクト>エクスポート)
{
exports-> set(string :: newsymbol( "add")、
functionTemplate :: new(add) - > getFunction());
}
node_module(アドオン、init)
コンパイル後、次のように使用できます。
コードコピーは次のとおりです。varアドオン= require( './ build/release/addon');
console.log(addon.add(1、1) + "b");
2Bが表示されます! ✧。٩(ᗜ)陳番*。
コールバック関数
前の章では、Hello Worldについてのみ話しました。この章では、おばあちゃんのマスターは良心を持ってそれを発見し、コールバック機能を書きました。
コンベンションのために、まずフレームワークを書きましょう。
コードコピーは次のとおりです。
#include <node.h>
名前空間V8を使用。
ハンドル<値> runcallback(const arguments&args)
{
ハンドルスコープスコープ。
// ...クラッキーなパチパチ型パチパチラシのクラックルクラックルクラックルクラックル
return scope.close(undefined());
}
次に、次のように使用する方法を決定します。
func(function(msg){
console.log(msg);
});
つまり、パラメーターをコールバック関数に渡し、文字列であると想像してから、表示して表示できます。
まず、文字列シリーズが必要です
これ以上苦労せずに、最初に文字列を与えましょう。 (√屈ε:)
しかし、node.jsコードが弱いため、この一連の汎用タイプを作成する必要があります。
local <value> :: new(string :: new( "hello world"));
何?あなたは私にローカル<値>とは何ですか?
次に、こことV8の参照ドキュメントを参照してください。
ドキュメントが示すように、ローカル<t>は実際にハンドル<t>から継承しており、前の章ではすでにハンドル<t>について話していたことを覚えています。
次に、これがローカルです。
ハンドルには、ローカルハンドルと永続的なハンドルの2つのタイプがあります。これらはローカル<t>です:ハンドル<t>と永続的な<t>:ハンドル<t>。前者とハンドル<t>の間に違いはありません。両方の生存サイクルは範囲内です。後者のライフサイクルはスコープから分離されています。ライフサイクルを終了するために、手動でPersistent ::廃棄を呼び出す必要があります。言い換えれば、ローカルハンドルは、C ++ `のスタックにオブジェクトを割り当てることと同等であり、永続的なハンドルは、ヒープ上のオブジェクトを割り当てるC ++と同等です。
次に、パラメーターテーブルシリーズが必要です
ターミナルコマンドラインでC/C ++を呼び出した後にコマンドラインパラメーターを取得する方法は?
コードコピーは次のとおりです。
#include <stdio.h>
void main(int argc、char* argv [])
{
// ...
}
ちなみに、ここのARGCはコマンドラインパラメーターの数であり、ARGV []はさまざまなパラメーターです。また、V8は同様の方法を使用してnode.jsのコールバック関数を呼び出します。
コードコピーは次のとおりです。v8exportローカル<値> v8 :: function :: call(handle <object> recv、
int argc、
ハンドル<値> argv []
);
~~ QAQはハンドル<Object> recvで立ち往生しています! ! !明日書き続けてください。 ~~
まあ、新しい日が始まり、私は強さに満ちているように感じます。 (∩^o^)⊃━☆゚*・。。
多くの側面(SegmentFault、StackoverFlow、QQグループ)で検証した後、上記の3つのパラメーターの意味を最終的に解決しました。
最後の2つのパラメーターについては説明しません。1つはパラメーターの数、もう1つはパラメーターの配列です。最初のパラメーターハンドル<オブジェクト> recvについては、stackoverflow兄弟の説明は次のとおりです。
JSで適用されるのと同じです。 JSでは、あなたはそうします
コードコピーは次のとおりです。
var context = ...;
cb.apply(context、[... args ...]);
最初の引数として渡されたオブジェクトは、関数範囲内でこれになります。 MDNに関する詳細なドキュメント。 JSがよくわからない場合は、JSのThisをこちらをご覧ください:http://unschooled.org/2012/03/understanding-javascript-this/
- Stackoverflowから抜粋
要するに、その関数は、呼び出された関数へのこのポインターを指定することです。この呼び出しの使用は、bind()、call()、およびapply()に類似しています。
したがって、私たちがしなければならないことは、最初にパラメーターテーブルを構築し、次にその実行のためにこの呼び出し関数を渡すことです。
最初のステップは、最初にオブジェクトタイプであったため、変換関数を表示することです。
local <function> cb = local <function> :: cast(args [0]);
2番目のステップは、パラメーターテーブル(配列)を作成することです。
local <value> argv [argc] = {local <value> :: new(string :: new( "hello world"))};
機能シリーズへの最終呼び出し
CBを呼び出して、次のパラメーターを渡します。
cb-> call(context :: getCurrent() - > global()、1、argv);
ここでの最初のパラメーターコンテキスト:: getCurrent() - >グローバル()は、グローバルコンテキストのこの関数を取得することを意味します。 2番目のパラメーターはパラメーターテーブルの数値です(結局のところ、node.jsの配列には長さの属性がありますが、システムは実際にはC ++の配列の長さを知りません。最後のパラメーターは、確立したパラメーターテーブルです。
最終的な章の終わりのファイルシリーズ
誰もがすでにこのステップに精通していると信じています。関数を書き、それをエクスポート機能に入れて、最後に宣言します。
コードを投稿するか、node.jsドキュメントに移動して読むだけです。
コードコピーは次のとおりです。
#include <node.h>
名前空間V8を使用。
ハンドル<値> runcallback(const arguments&args)
{
ハンドルスコープスコープ。
local <function> cb = local <function> :: cast(args [0]);
const unsigned argc = 1;
local <value> argv [argc] = {local <value> :: new(string :: new( "hello world"))};
cb-> call(context :: getCurrent() - > global()、argc、argv);
return scope.close(undefined());
}
void init(handle <object> exports、handle <object>モジュール)
{
モジュール - > set(string :: newsymbol( "Exports")、
functionTemplate :: new(runcallback) - > getFunction());
}
node_module(アドオン、init)
よくやった!自分で最後のステップに行きましょう。 JSでこの関数を呼び出すことに関しては、前に言及しました。
余分な
まあ、私の研究メモはますます抑制されていないと感じており、それらを壊したいと思っています〜
今日はここでやめましょう。学習ノートを書く過程で、コール関数のパラメーターの意味など、姿勢を再び増やしました。
この一連の学習メモがあなたに役立つと思うなら、私と一緒に来て楽しい時間を過ごしてください〜σ>(〃°ω°〃)♡→