用C/C++来实现 Node.js 的模块(二)

温故而知新,可以为湿矣

  首先请大家记住这个 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 了。

复制代码 代码如下:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgsfyw.html