Node.jsを使用して、評価側を含むNbutのオンライン裁判官を再構築するためにnode.jsを使用して、再構築する必要があります。 (それが完了したときに関しては、気にしないでください(/′)/〜
要するに、私たちが今やろうとしていることは、c/c ++を使用してnode.jsモジュールを実装することです。
準備
あなたが物事をうまくやりたいなら、あなたは最初にギャングのように振る舞い、あなたのツールを鋭くしなければなりません。
node-gyp
まず、ノードGYPモジュールが必要です。
任意のコーナーで、実行:
コードコピーは次のとおりです。
$ npmインストールnode -gyp -g
一連のBlahblahsの後、あなたはそれをインストールしました。
Python
その後、Python環境が必要です。
公式ウェブサイトにアクセスして、入手してください。
注:Node-GypのGitHubディスプレイによると、Pythonバージョンが2.5.0から3.0.0の間であることを確認してください。
編集環境
まあ、私はただ怠zyで、詳細に書いていません。コンパイラのニーズを確認するには、Node-Gypに移動してください。そして、大騒ぎします。
はじめる
公式ウェブサイトのHello Worldの紹介についてお話します。
こんにちは世界
たとえば、C ++ファイルを準備してください。たとえば、~~ sb.cc ~~ hello.ccと呼ばれます。
次に、段階的に段階的になり、最初にヘッダーファイルを作成し、名前空間を定義します。
コードコピーは次のとおりです。
#include <node.h>
#include <v8.h>
名前空間V8を使用。
主な関数
次に、返品値が<value>である関数を書きます。
コードコピーは次のとおりです。
ハンドル<値> hello(const arguments&args)
{
// ...書かれて空腹でした
}
次に、これらのことを大まかに分析します。
<value>を処理します
あなたは人生で正直でなければなりません。私はここからそれを参照することを事前に宣言します(@fool)。
V8は、ハンドルタイプを使用してJavaScriptオブジェクトをホストします。 C ++のS std :: sharedpointerと同様に、ハンドルタイプ間の割り当てはオブジェクト参照に直接渡されますが、違いは、V8がスマートポインターが一般的に使用する参照カウントではなく、独自のGCを使用してオブジェクトライフサイクルを管理することです。
JavaScriptタイプには、文字列、整数、オブジェクト、日付、配列など、C ++に対応するカスタムタイプがあり、JavaScriptの継承関係を厳密に順守しています。これらのタイプをC ++で使用する場合、ハンドルホスティングを使用してGCを使用して、ネイティブスタックやヒープを使用せずにライフサイクルを管理する必要があります。
V8エンジンのヘッダーファイルv8.hのさまざまな継承関係から見ることができるこのいわゆる値は、実際にはJavaScriptのさまざまなオブジェクトのベースクラスです。
これを理解した後、上記の関数ステートメントの意味を大まかに理解することができます。つまり、不確実なタイプの値を返すHello関数を記述します。
注:特定のタイプ、つまり文字列、整数などをハンドルホスティングの下に戻すことができます。
議論
これは、この関数で渡すパラメーターです。 node.jsでは、パラメーターの数がランダムであることを私たちは皆知っています。これらのパラメーターがC ++に渡されると、それらは引数型オブジェクトに変換されます。
後で特定の使用について話しましょう。ここでは、これが何であるかを理解する必要があります。 (それを秘密にするために?公式node.jsドキュメントの例が個別に議論されているため、最初のHello Worldの例(´థ౪థ)σについて話しているだけです
レンガとタイルを追加します
次に、貢献し始めます。最も単純な文章:
コードコピーは次のとおりです。
ハンドル<値> hello(const arguments&args)
{
ハンドルスコープスコープ。
return scope.close(string :: new( "world"));
}
これらの2つの文はどういう意味ですか?一般的な意味は、node.jsで文字列「world」を返すことです。
ハンドルスコープ
ここから同じ参照があります。
ハンドルのライフサイクルは、C ++スマートポインターのライフサイクルとは異なります。 C ++セマンティクス(つまり、{}に囲まれた部分)の範囲内で生き残ることはありませんが、ハンドルスコープを介して手動で指定する必要があります。ハンドルスコープは、スタックにのみ割り当てられます。ハンドルスコープオブジェクトが宣言された後、後で作成されたハンドルはハンドルスコープによって管理されます。ハンドルスコープオブジェクトが破壊された後、それによって管理されるハンドルはGCによって決定されます。
そのため、ライフサイクルを管理する必要がある場合は、この範囲を宣言する必要があります。わかりました、それで、なぜ私たちのコードはこのように書かれていないのですか?
コードコピーは次のとおりです。
ハンドル<値> hello(const arguments&args)
{
ハンドルスコープスコープ。
return string :: new( "world");
}
関数が戻ると、スコープが破壊され、管理するハンドルがリサイクルされるため、この文字列は無意味になります。
そこで、V8は魔法のアイデアを思いつきました - ハンドルスコープ:: close(handle <t> value)関数!この関数の目的は、スコープを閉じて、以前のスコープ管理、つまりこの関数を入力する前のスコープにパラメーターを引き渡すことです。
したがって、以前のコードscope.close(string :: new( "world"));
文字列:: new
文字列クラスは、node.jsのネイティブ文字列クラスに対応しています。バリュークラスから継承されます。同様に、次のことがあります。
•配列
•整数
•ブール
•物体
•日付
•番号
•関数
•...
これらのもののいくつかは価値から継承されていますが、他のものは二次から継承されます。ここではあまり研究しません。 V8コード(少なくともヘッダーファイル)を見たり、このマニュアルを見ることができます。
そして、この新しいことはどうですか?ここで見ることができます。新しい文字列オブジェクトを作成することです。
この時点で、この主な機能の解析を終了しました。
オブジェクトをエクスポートします
レビューしましょう。 node.jsで書かれている場合、機能またはオブジェクトをどのようにエクスポートしますか?
コードコピーは次のとおりです。
exports.hello = function(){}
それでは、C ++でこれを行うにはどうすればよいですか?
関数を初期化します
まず、初期化関数を書きましょう。
コードコピーは次のとおりです。
void init(ハンドル<オブジェクト>エクスポート)
{
// ...私はあなたの妹について書くことに腹を立てています! #゚Å ゚)⊂ち☆))゚)・∵)・∵
}
これはカメのお尻です!関数名か何かであるかは関係ありませんが、渡されたパラメーターはハンドル<オブジェクト>でなければなりません。つまり、以下のこの製品からエクスポートします。
次に、ここにエクスポートされたものを書きます。
コードコピーは次のとおりです。
void init(ハンドル<オブジェクト>エクスポート)
{
exports-> set(string :: newsymbol( "hello")、
functionTemplate :: new(hello) - > getFunction());
}
一般的な意味は、このエクスポートオブジェクトにhelloと呼ばれるフィールドを追加することであり、対応するものは関数であり、この関数は私たちの親愛なるhello機能です。
擬似コードで簡単なポイントを書くには:
コードコピーは次のとおりです。
void init(ハンドル<オブジェクト>エクスポート)
{
Exports.set( "Hello"、Function Hello);
}
作業が行われました!
(あなたの妹は終わった!黙って( 'するまった)ジェ
真のエクスポート
これが最後のステップであり、最終的にこれがエクスポートの入り口であることを宣言します。そのため、コードの最後にこの行を追加します。
node_module(こんにちは、init)
NIを服用しましたか? !これは何ですか?
心配しないでください、このnode_moduleはマクロです。つまり、initの初期化関数を使用して、エクスポートするものをHelloにエクスポートします。それで、このこんにちははどこから来たのですか?
ファイル名から来ています!はい、はい、それはファイル名から来ています。事前に宣言する必要はなく、使用できないことを心配する必要はありません。要するに、最終コンパイルされたバイナリファイルの名前は何ですか?ここでHelloに記入します。もちろん、接尾辞名を削除する必要があります。
詳細については、公式ドキュメントを参照してください。
すべてのノード追加が初期化関数をエクスポートする必要があることに注意してください。
コードコピーは次のとおりです。
void initialize(handle <object> exports);
node_module(module_name、initialize)
node_moduleの後にセミコロンは機能ではないため、セミコロンはありません(node.hを参照)。
module_nameは、最終的なバイナリのファイル名(.node接尾辞をマイナス)と一致させる必要があります。
コンパイル(๑•́ ́•̀๑)
さあ、一緒にコンパイルしましょう!
makefile -binding.gypに似た新しいアーカイブファイルを作成しましょう。
そして、次のようなコードを追加します:
コードコピーは次のとおりです。
{
「ターゲット」:[
{
"Target_name": "hello"、
「ソース」:["hello.cc"]
}
]
}
なぜこれを書くのですか? Node-Gypの公式ドキュメントを参照できます。
設定します
ファイルの準備ができたら、このディレクトリでこのコマンドを実行する必要があります。
コードコピーは次のとおりです。
$ node-gyp configure
すべてが問題ない場合は、ビルドディレクトリを生成し、その後、プラットフォームに応じて、M $ Visual Studio VCXProjファイルなど、またはMakeFileなどに関連するファイルがあります。
建てる
MakeFileが生成された後、構築とコンパイルを開始します。
$ node-gypビルド
すべてがコンパイルされた場合にのみ、実際のタスクが完了すると見なされます!信じられない場合は、ビルド/リリースディレクトリを確認してください。以下にhello.Nodeファイルはありますか?そうです、これはC ++がNode.jsのためにピックアップしたいSOAPです!
基本を手に入れましょう!ノード(✿゚゚)ノC++
今すぐディレクトリに新しいファイルjianfeizao.jsを作成します。
コードコピーは次のとおりです。
var addon = require( "./ build/release/hello");
console.log(addon.hello());
それを見るかどうか!それを見るかどうか!出てくる! node.jsとC ++の結果が基本を取得しました!このaddon.hello()は、以前にc ++コードで書いたハンドル<value> hello(const arguments&args)です。これで返される値を出力しました。
シャワーを浴びて寝ると、次のセクションがより深いです
遅くなっているので、今日は書くことになります。これまでのところ、誰もが最も基本的なHello World C ++拡張機能を思いつくことができます。次回書くときは、次回がいつになるのかわかりません。
(ねえ、ねえ、マスターはどうしてそんなに無責任になることができますか!