前面三篇介绍文章:
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
也有封装。更多的接口以及详细的使用方式,能够查阅它的文档。