UPD:環境のセットアップ
VS2010のコンパイルと構成に使用しました。
まず、ソースnode.jsをダウンロードし、ルートにあるvcbuild.batを解凍して実行します。 vcbuild.batは、Visual Studioと構成に必要なプロジェクトを作成します。 バッチファイルを機能させるには、Python 2.7が必要です。 次に、
npm install node-gyp
。
次に、Visual Studioでプロジェクト(CLR Empty Project)を作成し、プロジェクトプロパティに移動し、構成タイプを.dllに、拡張子を.nodeに変更し、CLR環境サポートをインストールします。 ディレクトリセクションに移動し、包含ディレクトリで次のフォルダへのパスを追加します
node-v0.8.15\deps\v8\include
node-v0.8.15\deps\uv\include
node-v0.8.15\src
次に、ソースコードファイルを追加します。 この段階で、VS(オプション)を終了して、お気に入りのNotepad / Sublime / WebStormを開くことができます。
次に、ソースディレクトリに移動し、そこにbinding.gypファイルを作成します。このファイルは、node-gypユーティリティにアプリケーションのビルド方法とビルド元を伝えます。 私の例では、それは非常にシンプルで簡単です。
{ "targets": [ { "target_name": "getSummAsync", "sources": [ "async.cpp" ] } ] }
これでコンパイルできます。 binding.gypという行に
node-gyp configure
を
node-gyp configure
したディレクトリにコンソールで書き込み、次に
node-gyp build
コンパイルされたモジュールはbuild / Releaseフォルダーになります
例自体
システムコールは使用しません。 これには特別な意味はありません。例が複雑になるだけです。 それでは、始めましょう。
たとえば、整数の配列を渡し、その合計をカウントし、正の要素を取得してユーザーに返します。
まず、構造体を宣言し、その構造体で必要なデータ構造体を宣言します。
struct Summ_req { vector<int> numbers; vector<int> gtz; int result; Persistent<Function> callback; };
これは、数値を格納するベクトルです。
vector<int> numbers;
ゼロより大きい数値を格納するベクトル。
vector<int> gtz;
ここに結果を保存します
int result;
ベクトルを使用する理由を理解することは重要ですが、標準のv8テンプレートでうまくいくようです。 しかし、これはそうではありません。 詳細については、以下をご覧ください。
モジュールには、node.jsから呼び出すメイン関数と、実際にはモジュールを非同期にする他の2つの3つの関数があります。
仕事関数
getSummAsyncは、要素の配列とコールバックの2つの引数を受け入れます。 関数が呼び出されるパラメーターが正しいかどうかを確認します。パラメーターが正しい場合はカスタマイズします。つまり、引数と通信できるようにするには、目的の型に変換する必要があります。
Local<Function> callback = Local<Function>::Cast(args[1]); Local<Array> numbers = Local<Array>::Cast(args[0]);
次に、構造体を初期化してコールバックを渡し、配列をベクターに書き込みます。
Summ_req* request = new Summ_req; request->callback = Persistent<Function>::New(callback); for (size_t i = 0; i < numbers->Length(); i++) { request->numbers.push_back(numbers->Get(i)->Int32Value()); }
永続性が望ましいのは、 それでも、この関数だけでなくコールバックも使用されます。
そして、ワーカーを順番に起動します。
uv_queue_work(uv_default_loop(), req, Worker, After);
getSummAsync
static Handle<Value> getSummAsync (const Arguments& args) { HandleScope scope; if (args.Length() < 2 || !args[0]->IsArray()) { return ThrowException(Exception::TypeError(String::New("Bad arguments"))); } if (args[1]->IsFunction()) { Local<Function> callback = Local<Function>::Cast(args[1]); Local<Array> numbers = Local<Array>::Cast(args[0]); Summ_req* request = new Summ_req; request->callback = Persistent<Function>::New(callback); for (size_t i = 0; i < numbers->Length(); i++) { request->numbers.push_back(numbers->Get(i)->Int32Value()); } uv_work_t* req = new uv_work_t(); req->data = request; uv_queue_work(uv_default_loop(), req, Worker, After); } else { return ThrowException(Exception::TypeError(String::New("Callback missing"))); } return Undefined(); }
ワーカー機能では、すべてが明確だと思います。 数値をカウントし、結果を構造に返します。 次に、v8ツールではなくベクターを使用する理由について説明します。 Worker関数は別のスレッドで動作し、node.jsとv8では1つのスレッドのみがjsを実行できます。つまり、別のスレッドでv8配列を作成することはできません。
労働者
void Worker(uv_work_t* req) { Summ_req* request = (Summ_req*)req->data; request->result = 0; for (vector<int>::iterator it = request->numbers.begin(); it != request->numbers.end(); ++it) { request->result += *it; if (*it > 0) { request->gtz.push_back(*it); } } // request->result = request->int1 + request->int2; }
これでAfter関数です。 Workerが機能した後、After関数が呼び出されます。この関数は既にnode.jsにデータを返すことができます。
ここで、Worker関数ではなく、上記で説明した理由により、結果の配列を取得します。
Handle<Value> argv[2];
ここに戻り値を入れます
request->callback->Call(Context::GetCurrent()->Global(), 2, argv);
そして、argvに書き込まれたパラメーターを使用してコールバックを呼び出します。
後
void After(uv_work_t* req) { HandleScope scope; Summ_req* request = (Summ_req*)req->data; delete req; Handle<Value> argv[2]; argv[0] = Integer::New(request->result); Local<Array> gtz = Array::New(); size_t i = 0; for (vector<int>::iterator it = request->gtz.begin(); it != request->gtz.end(); ++it) { gtz->Set(i, Integer::New(*it)); i++; } argv[1] = gtz; TryCatch try_catch; request->callback->Call(Context::GetCurrent()->Global(), 2, argv); if (try_catch.HasCaught()) { FatalException(try_catch); } request->callback.Dispose(); delete request; }
node-gypユーティリティを使用してコンパイルした後、node.jsからモジュールを呼び出すことができます。
var foo = require('./getSummAsync.node') foo.getSummAsync([1,2,3,6,-5],function(a, b){ console.log(a, b); });
結果
7 [ 1, 2, 3, 6 ]
これは私の最初の記事です、私をあまりscらないでください。
ご質問がある場合は、お問い合わせください!
参照資料