昨天研究了下如何用C++和node交互,在node的程序中,若是有大數據量的計算,處理起來比較慢,能夠用C++來處理,而後經過回調(callback的形式),返回給node。node
首先,先來看看node 是如何和C++交互吧。c++
前提:須要安裝nodejs 環境,安裝node-gyp 包。採用npm 方式安裝,這個太方便了,修改本文件夾下面的package.json 依賴選項,而後執行npm install 就能夠了。git
1.以hello world 爲例來講明:github
1)創建一個文件夾hello,在這個文件夾裏依次添加3個文件,hello.cc, binding.gyp,test.js (其中hello.cc 是c++的源程序文件,binding.gyp 是編譯模塊的配置文件,這個文件被npm
node-gyp程序編譯,test.js是nodejs的調用程序。)json
文件下結構以下:函數
hello.cc 代碼以下:測試
#include <node.h> #include <v8.h> using namespace v8; Handle<Value> Method(const Arguments& args) { HandleScope scope; return scope.Close(String::New("hello,world")); } void init(Handle<Object> exports) { exports->Set(String::NewSymbol("hello"), FunctionTemplate::New(Method)->GetFunction()); } NODE_MODULE(hello, init)
binding.gyp以下:大數據
{ "targets": [ { "target_name": "hello", "sources": [ "hello.cc" ] } ] }
test.js 爲:ui
var addon = require('./build/Release/hello'); console.log(addon.hello());
2) 直接執行 node-gyp configure build 就直接編譯了。
3) 運行 node test.js 就輸出結果。
好了,就這麼簡單。node就能夠直接調用C++編寫的程序。
對上面程序的解釋:在hello.cc 中,咱們首先建立了一個函數Method, 此函數返回一個"hello,world"的字符串,後面咱們又建立了一個init的函數,做爲一個初始化函數,咱們去調用了一個函數
最後面,咱們將這個模塊綁定爲:NODE_MODULE(hello, init)
在官網中指出,全部的node的插件必須輸出一個初始化的函數,也就是說以下代碼是在每一個模塊都必須有的,固定格式。
void Initialize (Handle<Object> exports); NODE_MODULE(module_name, Initialize)
其中 module_name 必須對應上binding.gyp中的
target_name 就能夠了。
通過了node-gyp configure build 編譯之後會在當前文件下生成一個build 的新的文件夾。咱們經過在test.js中去引用這個build的結果,就能夠調用C++的寫的程序了。
OK,一個簡單的node與C++程序就寫完了。
如今這樣node就能夠和C++寫的程序交互了,直接去調用C++寫的程序了。若是以爲node處理不過來,均可以經過C++來處理。
2.node 經過callback 回調的方式,調用C++處理後的結果返回給node
1)按照上面的方式,首先創建3個文件 callback.cc, binding.gyp,test.js
callback.cc:
#define BUILDING_NODE_EXTENSION #include <node.h> using namespace v8; Handle<Value> RunCallback(const Arguments& args) { HandleScope scope; 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> module) { module->Set(String::NewSymbol("exports"), FunctionTemplate::New(RunCallback)->GetFunction()); } NODE_MODULE(callback, Init)
binding.gyp:
{ "targets": [ { "target_name": "callback", "sources": [ "callback.cc" ] } ] }
test.js:
var addon = require('./build/Release/callback'); addon(function(msg){ console.log(msg); // 'hello world' });
2)編譯,在終端輸入:node-gyp configure build ,會在當前目錄下生成一個build 的新文件下
3)測試,node test.js 輸出 //hello world
注意:若是有多個.cc 的文件,必定要將他們都包含在binding.gyp中,否則編譯是經過了,可是node調用會報錯。
測試代碼地址:https://github.com/yupeng528/node-addon-test