用NAN写一个nodejs的c++扩展

7次阅读

共计 2064 个字符,预计需要花费 6 分钟才能阅读完成。

NAN 介绍
NAN 的全称为 Native Abstraction for Node.js, 其表现上是一个 Node.js 包。安装后,就得到一堆 C ++ 头文件,里面是一堆宏。它主要为 Node.js 和 V8 跨版本提供了封装的宏,使得开发者不用关心各个版本之间的 API 的差异。(from《nodejs 来一打 C ++ 扩展》)
NAN 的优势在于可以屏蔽不同版本 Node 的 API,使得 C ++ 扩展可以 wirte once, compile anywhere,一份 C ++ 扩展可以适用于不同版本的 Node.js。这里的 c ++ 扩展实现的功能是一个求和的扩展 (hello world 太多了,写个不一样的) 扩展地址为:https://www.npmjs.com/package…,项目代码地址:https://github.com/warjiang/d… 使用方式如下:
项目目录如下:
在开发之前我们首先需要安装 nan 包(npm install nan -S)。扩展开发分成两个层面,c++ 层面和 JS 层面。src 目录中主要是 c ++ 代码,也是扩展的实现部分。index.js 引用 c ++ 扩展,暴露出方法供上层使用。初次开发 nodejs 扩展的用户需要注意下项目目录中的 binding.gyp 文件(node-gyp 会读取项目中的 binding.gyp):target_name 为 sum, 表示最后生成的扩展文件名为 sum.node。include_dirs 表示除了 nodejs 基础的依赖之外,我们还需要 nan 的头文件,<!(node -e \”require(‘nan’)\”) 中 <! 表示后面是命令,node -e “require(‘nan’)” 就是利用 nodejs 的 require 能力,寻找 nan 的目录,执行效果如下:sources 项指明了 c ++ 扩展需要编译的源文件。
c++ 部分开发
先直接上代码(src/init.cc):
#include <v8.h>
#include <node.h>
#include <nan.h>
using v8::Local;
using v8::Object;
using v8::Number;

NAN_METHOD(sum){
Nan::HandleScope scope;
uint32_t sum = 0;
for(int i = 0; i< info.Length(); i++){
sum += info[i]->NumberValue();
}
info.GetReturnValue().Set(Nan::New(sum));
}

void init (Local<Object> exports)
{
Nan::HandleScope scope;
Nan::SetMethod(exports, “sum”, sum);
}

NODE_MODULE(memwatch, init);
扩展的入口从 NODE_MODULE(memwatch, init); 开始,当 js 层面执行了 require(‘path/to/xxx.node’)的时候,就会执行 init 函数。init 函数的入参可以类比 module.exports 对象,这里我们给 exports 对象增加了一个名为 sum 的方法,其对应的实现为 NAN_METHOD(sum)部分。NAN_METHOD(sum)通过宏定义对 sum 函数进行包装,sum 函数的入参为 info 数组,我们再这里遍历 info 数组,通过 info[i]->NumberValue 方法将每个入参对应的 number 类型的值取出来,加到 sum 中去。累加完成后通过 info.GetReturnValue().Set(Nan::New(sum))将 sum 结果返回出去。这样其实我们的 c ++ 部分扩展就已经开发完毕了,可以通过执行 node-gyp configure && node-gyp build 编译项目,在 build/Release 目录下会生成 sum.node 的文件。我们可以启动一个 node 的命令行进行验证:
// node cli
> let addon = require(‘./build/Release/sum’)
> addon.sum(1) // 1
> addon.sum(1,2) // 3
引用 build/Release/sum 的方式实际开发中十分不方便,我们可以用 js 对这行代码进行封装,在 js 内部引用 build/Release/sum,暴露出来方法给外部进行调用。
js 部分开发
有了上面的铺垫,这里我们开发 js 部分就显得十分自然。直接上代码
const addon = require(‘./build/Release/sum’)
module.exports = addon.sum
一共就两行代码,逻辑清晰简单,就引用编译好的扩展,将 sum 方法暴露出去。
发布
nodejs 扩展发布的时候需要在 package.json 的 scripts 部分增加 install 钩子的处理,如下:用户安装扩展的时候,会在 install 的钩子上,帮助用户执行 node-gyp rebuild 来在用户的机器上生成对应的扩展文件。这样我们的开发就完毕了,执行 npm publish 将 npm 包发布出去

正文完
 0