void SleepFunc(const v8::FunctionCallbackInfo<Value>& args) {
Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);
double arg0 = args[0] -> NumberValue();
Sleep(arg0);
}
void Init(Handle<Object> exports) {
Isolate* isolate = Isolate::GetCurrent();
exports->Set(String::NewFromUtf8(isolate, "sleep"),
FunctionTemplate::New(isolate, SleepFunc)->GetFunction());
}
NODE_MODULE(hello, Init);
node 0.10及以下版本:
复制代码 代码如下:
#include <node.h>
#include <v8.h>
using namespace v8;
Handle<Value> SleepFun(const Arguments& args) {
HandleScope scope;
double arg0 = args[0] -> NumberValue();
Sleep(arg0);
return scope.Close(Undefined());
}
void Init(Handle<Object> exports) {
exports->Set(String::NewSymbol("sleep"),
FunctionTemplate::New(SleepFun)->GetFunction());
}
NODE_MODULE(hello, Init);
可以看出,变化还是相当大的,如果能屏蔽这些差异就太好了,有办法了?我写这么多还不就是想告诉你有办法。是时候请出nan库了。
nan
还记得在binding.gyp中,我们引入nan库的路径,就是要在这里用。nan库是干嘛的呢?它提供了一层抽象,屏蔽了nodejs 0.8、nodejs 0.10、nodejs 0.12、io.js之前addon的语法差异。赞!
先安装: npm install --save nan ,看看同样的功能,用了nan后如何实现:
复制代码 代码如下:
#include <nan.h>
using namespace v8;
NAN_METHOD(Sleep){
NanScope();
double arg0=args[0]->NumberValue();
Sleep(arg0);
NanReturnUndefined();
}
void Init(Handle<Object> exports){
exports->Set(NanSymbol("sleep"), FunctionTemplate::New(Sleep)->GetFunction());
}
NODE_MODULE(hello, Init);
你需要了解的就是nan这套东西,至于v8的那一套就可以不用关注。
从下往上看:
复制代码 代码如下:
NODE_MODULE(hello, Init);
这句定义addon的入口。注意第一个参数要与我们在binding.gyp中target_name一项一致。第二个参数就是addon的入口函数。
复制代码 代码如下:
void Init(Handle<Object> exports){
exports->Set(NanSymbol("sleep"), FunctionTemplate::New(Sleep)->GetFunction());
}
这段代码就是addon的入口方法。它接收两个参数,分别是exports和module。上面的示例省略了第二个参数。如果模块提供一个对象,可以像示例中那个,直接给exports指定要提供的key-value;如果特殊一点,仅提供一个数值,或一个函数,则需要用到第二个参数,类似于 NODE_SET_METHOD(module, "exports", foo); 。这个示例中是表示要输出这样一个模块:
复制代码 代码如下:
{
"sleep": Sleep
}
Sleep是一个函数,下来就来看看Sleep的定义:
复制代码 代码如下:
NAN_METHOD(Sleep){
NanScope();
double arg0=args[0]->NumberValue();
Sleep(arg0);
NanReturnUndefined();
}
其实就是读取javascript传入的参数,转成double型,再调用c++的sleep方法。
编译addon
下面就要开始编译这个模块了。首先执行 node-gyp configure 来进行构建前准备工作,它会生成一个build文件夹和一些文件。接下来运行 node-gyp build 就可以开始编译了。在这个示例中,最终会在/build/Release/目录下生成一个hello.node文件,这就是最终能被javascript引用的addon模块了。
如果后续对c++代码有修改,就不用再运行 node-gyp configure ,直接运行 node-gyp build 就好。
nodejs使用
建立一个index.js,看看怎么用这个模块吧:
复制代码 代码如下:
var sleep=require('./build/Release/hello.node').sleep;
console.log(new Date);
sleep(1000);
console.log(new Date);