前面三篇介紹文章:
Node.js C++ addon編寫實戰(一)之node-gyp
Node.js C++ addon編寫實戰(二)之對象轉換
Node.js C++ addon編寫實戰(三)之Bufferhtml
Node.js 日趨成熟,即將要發佈 v1.0 版本,可是在成長過程當中,不得不有一些 API 的變化。在從 v0.10 向 v0.11/v0.12 升級的過程當中,就致使了幾處 C++ addon 編寫上的變化。node
在API changes between v0.10 and v0.12中咱們發現:linux
All
node::Buffer::New()
variants now returnLocal<Object>
instead ofBuffer*
.git
咱們再也不須要經過 Buffer::New(str, 100)->handle_
來獲取能傳遞給 js 的 Buffer 對象了,New 出來的就已是 v8 對象了。github
同時,在 node v0.11.4+ 的版本,v8 進行了一次大的升級,API 有一些大的調整,經過一個小例子來展現這一套新的 API 在使用上的變化:函數
//in node 0.10 Handle<Value> Add(const Arguments& args) { HandleScope scope; if (args.Length() < 2) { ThrowException(Exception::TypeError(String::New("Wrong number of arguments"))); return scope.Close(Undefined()); } if (!args[0]->IsNumber() || !args[1]->IsNumber()) { ThrowException(Exception::TypeError(String::New("Wrong arguments"))); return scope.Close(Undefined()); } Local<Number> num = Number::New(args[0]->NumberValue() + args[1]->NumberValue()); return scope.Close(num); } //in node 0.11.4+ template<class T> void Add(const v8::FunctionCallbackInfo<T>& info) { Isolate* isolate = Isolate::GetCurrent(); HandleScope scope(isolate); if (info.Length() < 2) { ThrowException(Exception::TypeError( String::New("Wrong number of arguments"))); info.GetReturnValue().SetUndefined(); return; } if (!info[0]->IsNumber() || !info[1]->IsNumber()) { ThrowException(Exception::TypeError(String::New("Wrong arguments"))); info.GetReturnValue().SetUndefined(); return; } Local<Number> num = Number::New(info[0]->NumberValue() + info[1]->NumberValue()); info.GetReturnValue().Set(num); }
能夠看到,變化主要在函數聲明、 HandleScope
初始化以及如何返回數據這三點上。spa
在 linux (Red Hat Enterprise Linux Server release 5.7 (Tikanga)) 和 node v0.11.8 下編譯個人一個 C++ addon 的時候,出現了一個詭異的Bug,調用: v8::Value::ToInteger()
這個方法的時候會在連接的時候報錯 undefined symbol
, 最終沒有找到緣由,經過 V8::Value::IntegerValue()
替換了以前的實現,一切恢復正常。code
nan
上面廢話了這麼多來談談 node 升級致使的 C++ addon 兼容性問題,是否是很想寫一個輔助模塊來把這些變化所有封裝起來? 別急,早就有大神作了這件事情:nan 是 rvagg(iconv 和 levelup 的做者) 發起維護的一個輔助模塊,最近TooTallNate(node-gyp做者,node開發組成員)也加入開始維護這個模塊。htm
A header file filled with macro and utility goodness for making add-on development for Node.js easier across versions 0.8, 0.10 and 0.11, and eventually 0.12.對象
經過 nan
來簡化上面的示例代碼:
//with nan #include "nan.h" NAN_METHOD(Add) { NanScope(); if (args.Length() < 2) { ThrowException(Exception::TypeError(String::New("Wrong number of arguments"))); NanReturnUndefined(); } if (!args[0]->IsNumber() || !args[1]->IsNumber()) { ThrowException(Exception::TypeError(String::New("Wrong arguments"))); NanReturnUndefined(); } Local<Number> num = Number::New(args[0]->NumberValue() + args[1]->NumberValue()); NanReturnValue(num); }
經過 nan
,不再用管兼容性問題,也不須要些那麼一長串的函數聲明瞭。固然,它不僅僅是解決了這個問題,上面提到的 Buffer API
的變動, nan
也有封裝。更多的接口以及詳細的使用方式,能夠查閱它的文檔。