ホームページ >ウェブフロントエンド >jsチュートリアル >C/Cを使用してNode.jsモジュールを実装する(2)_node.js
過去を振り返り、新しいことを学ぶと幸せになれます
まず最初に、この V8 オンライン マニュアル (http://izs.me/v8-docs/main.html) を思い出してください。
前回のbuilding.gypファイルをまだ覚えていますか?
これと同じように、*.cc ファイルがさらにいくつかある場合は、次のようになります:
"ソース": [ "addon.cc", "myexample.cc" ]
前回は 2 つのステップに分けましたが、実際には、構成とコンパイルは次のようにまとめることができます。
$node-gypconfigurebuild
はい、続けましょう。
目次
関数パラメータ
いよいよパラメータについて話さなければなりません。
a と b を加算して結果を返す関数 add(a, b) があると仮定して、最初に関数の概要を記述します。
{
HandleScope スコープ;
}
これは関数のパラメータです。まずはv8の公式マニュアルリファレンスを見てみましょう。
•int Length() const
•ローカル 演算子[](int i) const
残りは気にしない、この 2 つが重要です。 1 つは関数に渡されるパラメーターの数を表し、もう 1 つの括弧は添字インデックスを介して n 番目のパラメーターにアクセスするために使用されます。
角括弧内のインデックス演算子は、Node.js のすべての型の基本クラスである Local
•IsArray()
•IsBoolean()
•IsDate()
•IsFunction()
•IsInt32()
•IsNativeError()
•IsNull()
•IsNumber()
•IsRegExp()
•IsString()
•...
それらを 1 つずつリストするつもりはありません。残りについてはドキュメントを読んでください。 。:.゚ヽ(*´∀`)ノ゚.:。
これは後で使用する関数です。詳細については、v8 のドキュメントを参照してください。
名前が示すように、エラーをスローします。このステートメントの実行後は、Node.js ローカル ファイルで throw() ステートメントを実行するのと同じになります。例:
ThrowException(Exception::TypeError(String::New("引数の数が間違っています")));
throw new TypeError("引数の数が間違っています");
この関数はドキュメントにも記載されています。
具体的には、一部の関数は特定の値を返す必要がないか、現時点では戻り値がないため、これは null 値です。
やってみよう、サオニアン!
上記の点を理解すれば、すぐに a b のロジックを書けるようになると思います。Node.js 公式マニュアルからコードをコピーして、実行してみましょう。
ハンドル<値> Add(const Arguments& args)
{
HandleScope スコープ;
// 3 つ以上のパラメータを渡すことができることを意味しますが、実際には最初の 2 つだけを使用します
If(args.Length()
{
// エラーをスローします
ThrowException(Exception::TypeError(String::New("引数の数が間違っています")));
// null 値を返す
returnscope.Close(Unknown());
}
If(!args[0]->IsNumber() || !args[1]->IsNumber())
{
// エラーをスローし、null 値を返します
ThrowException(Exception::TypeError(String::New("Wrong argument")));
returnscope.Close(Unknown());
}
//
http://izs.me/v8-docs/classv8_1_1Value.html#a6eac2b07dced58f1761bbfd53bf0e366)
// `NumberValue` 関数
ローカル<数値> num = Number::New(args[0]->NumberValue() args[1]->NumberValue());
}
最後にexport関数を記述すればOKです。
コールバック関数
前の章では、Hello world についてのみ説明しました。この章では、おばあちゃんが意識的な発見をし、別のコールバック関数を作成しました。
いつものように、最初にフレームワークを作成します。
{
HandleScope スコープ;
returnscope.Close(Unknown());
}
func(関数(msg) {
console.log(msg);
});
つまり、パラメータをコールバック関数に渡し、それを console.log() で出力できると想定します。
まず文字列シリーズが必要です
早速、最初に文字列を与えてから、それについて話しましょう。 (√ ε :)
ただし、Node.js コードの型指定が弱いため、この文字列をユニバーサル型にする必要があります。
Local
え? Local
それでは、それについて少しお話しさせてください。ここと V8 リファレンス ドキュメントを参照してください。
ドキュメントに示されているように、Local
それではローカルについて話しましょう。
ハンドルにはローカル ハンドルと永続ハンドルの 2 種類があり、それぞれローカル
次に、パラメータテーブルシリーズが必要です
ターミナルのコマンドラインから C/C を呼び出した後、コマンドラインパラメータを取得するにはどうすればよいですか?
void main(int argc, char* argv[])
{
// ...
}
ちなみに、ここでのargcはコマンドラインパラメータの数、argv[]は各パラメータです。次に、Node.js のコールバック関数を呼び出します。v8 も同様の方法を採用しています。
~~QAQ が Handle
多くの側面 (SegmentFault、StackOverflow、KouKou グループ) で検証した結果、上記の関数の 3 つのパラメーターの意味が最終的に解決されました。
次の 2 つのパラメータについては多くは説明しません。1 つはパラメータの数で、もう 1 つはパラメータの配列です。最初のパラメータ Handle
JS での apply と同じです。
最初の引数として渡されるオブジェクトは、関数スコープ内で this になります。JS について詳しくない場合は、ここで JS の詳細を参照してください。http://unschooled.org /2012/03/undering-javascript-this/
——StackOverflow
つまり、その機能は呼び出される関数の this ポインタを指定することです。この Call の使用法は、JavaScript の binding()、call()、および apply() に似ています。
したがって、私たちがしなければならないことは、最初にパラメータテーブルを構築し、次に実行のために Call 関数を渡すことです。
最初のステップは変換関数を表示することです。変換関数は元々オブジェクト型であるためです。
ローカル<関数> cb = ローカル<関数>::Cast(args[0]);
2 番目のステップは、パラメーター テーブル (配列) を作成することです:
Local
ラストコール機能シリーズ
cb を呼び出してパラメータを渡します:
cb->Call(Context::GetCurrent()->Global(), 1, argv);
ここでの最初のパラメータ Context::GetCurrent()->Global() は、関数の this としてグローバル コンテキストを取得することを意味します。2 番目のパラメータはパラメータ テーブル内の番号です (結局、Node.js ですが)。配列には長さ属性がありますが、実際にはシステムは C の配列の長さを知らないため、配列の長さを示すために自分で数値を渡す必要があります); 最後のパラメーターは作成したばかりのパラメーター テーブルです。 。
最終章ファイナルドキュメントシリーズ
関数を作成し、それをエクスポートされた関数に入れて、最後に宣言するというこのステップについては、誰もがすでによく知っていると思います。
コードを直接リリースするだけですが、Node.js ドキュメントに直接アクセスすることもできます。
ハンドル<値>RunCallback(const Arguments& args)
{
HandleScope スコープ;
ローカル cb = ローカル::Cast(args[0]);
const unsigned argc = 1;
Local
cb->Call(Context::GetCurrent()->Global(), argc, argv);
returnscope.Close(Unknown());
}
void Init(Handle
NODE_MODULE(アドオン、初期化)
完了しました。残りの手順は自分で実行してください。この関数を JS で呼び出すことについては、以前に説明しました。
追加
さて、勉強ノートがどんどん自由になってきている気がしますので、分解してください~
今日はこの辺で、勉強ノートを書いている途中でCall関数のパラメータの意味などでまた困ってしまいました。
この一連の学習ノートがまだ役立つと思われる場合は、ぜひ一緒に楽しんでください〜Σ>―(〃°ω°〃)♡→