温故而知新,可以为湿矣
首先请大家记住这个 V8 的在线手册——。
还记得上次的 building.gyp 文件吗?
复制代码 代码如下:
{
"targets": [
{
"target_name": "addon",
"sources": [ "addon.cc" ]
}
]
}
就像这样,举一反三,如果多几个 *.cc 文件的话就是这样的:
"sources": [ "addon.cc", "myexample.cc" ]
上次我们把俩步骤分开了,实际上配置和编译可以放在一起的:
$ node-gyp configure build
复习完了吗?没?!
好的,那我们继续吧。
表番
函数参数
现在我们终于要讲参数了呢。
让我们设想有这样一个函数 add(a, b) 代表把 a 和 b 相加返回结果,所以先把函数外框写好:
复制代码 代码如下:
#include <node.h>
using namespace v8;
Handle<Value> Add(const Arguments& args)
{
HandleScope scope;
//... 又来!
}
Arguments
这个就是函数的参数了。我们不妨先看看 v8 的官方手册参考。
•int Length() const
•Local<Value> operator[](int i) const
其它的我们咱不关心,这两个可重要了!一个代表传入函数的参数个数,另一个中括号就是通过下标索引来访问第 n 个参数的。
所以如上的需求,我们大致就可以理解为 args.Length() 为 2,args[0] 代表 a 以及 args[1] 代表 b 了。并且我们要判断这两个数的类型必须得是 Number。
注意到没,中括号的索引操作符返回结果是一个 Local<Value> 也就是 Node.js 的所有类型基类。所以传进来的参数类型不定的,我们必须得自己判断是什么参数。这就关系到了这个 Value 类型的一些函数了。
•IsArray()
•IsBoolean()
•IsDate()
•IsFunction()
•IsInt32()
•IsNativeError()
•IsNull()
•IsNumber()
•IsRegExp()
•IsString()
•...
我就不一一列举了,剩下的自己看文档。。:.゚ヽ(*´∀`)ノ゚.:。
ThrowException
这个是我们等下要用到的一个函数。具体在 v8 文档中可以找到。
顾名思义,就是抛出错误啦。执行这个语句之后,相当于在 Node.js 本地文件中执行了一条 throw() 语句一样。比如说:
ThrowException(Exception::TypeError(String::New("Wrong number of arguments")));
就相当于执行了一条 Node.js 的:
throw new TypeError("Wrong number of arguments");
Undefined()
这个函数呢也在文档里面。
具体就是一个空值,因为有些函数并不需要返回什么具体的值,或者说没有返回值,这个时候就需要用 Undefined() 来代替了。
动手吧骚年!
在理解了以上的几个要点之后,我相信你们很快就能写出 a + b 的逻辑了,我就把 Node.js 官方手册的代码抄过来给你们过一遍就算完事了:
复制代码 代码如下:
#include <node.h>
using namespace v8;
Handle<Value> Add(const Arguments& args)
{
HandleScope scope;
// 代表了可以传入 2 个以上的参数,但实际上我们只用前两个
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());
}
// 具体参考 v8 文档
// )
// 的 `NumberValue` 函数
Local<Number> num = Number::New(args[0]->NumberValue() + args[1]->NumberValue());
return scope.Close(num);
}
函数大功告成!
最后把尾部的导出函数给写好就 OK 了。
复制代码 代码如下: