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

栏目: C++ · 发布时间: 7年前

内容简介:NAN的全称为Native Abstraction for Node.js, 其表现上是一个Node.js包。安装后,就得到一堆C++头文件,里面是一堆宏。它主要为Node.js和V8跨版本提供了封装的宏,使得开发者不用关心各个版本之间的API的差异。(from 《nodejs来一打C++扩展》)在开发之前我们首先需要安装nan包(

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/sum-addon,

项目代码地址: https://github.com/warjiang/devcat/tree/master/backend/sum-addon

使用方式如下:

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

项目目录如下:

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

在开发之前我们首先需要安装nan包( npm install nan -S )。扩展开发分成两个层面,c++层面和JS层面。src目录中主要是c++代码,也是扩展的实现部分。index.js引用c++扩展,暴露出方法供上层使用。

初次开发nodejs扩展的用户需要注意下项目目录中的binding.gyp文件(node-gyp会读取项目中的binding.gyp):

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

target_name为sum,表示最后生成的扩展文件名为 sum.node 。include_dirs表示除了nodejs基础的依赖之外,我们还需要nan的头文件, <!(node -e \"require('nan')\")<! 表示后面是命令, node -e "require('nan')" 就是利用nodejs的require能力,寻找nan的目录,执行效果如下:

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

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钩子的处理,如下:

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

用户安装扩展的时候,会在install的钩子上,帮助用户执行 node-gyp rebuild 来在用户的机器上生成对应的扩展文件。这样我们的开发就完毕了,执行 npm publish 将npm包发布出去


以上所述就是小编给大家介绍的《用 NAN 写一个 nodejs 的 C++ 扩展》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

High Performance JavaScript

High Performance JavaScript

Nicholas C. Zakas / O'Reilly Media / 2010-4-2 / USD 34.99

If you're like most developers, you rely heavily on JavaScript to build interactive and quick-responding web applications. The problem is that all of those lines of JavaScript code can slow down your ......一起来看看 《High Performance JavaScript》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

URL 编码/解码
URL 编码/解码

URL 编码/解码

html转js在线工具
html转js在线工具

html转js在线工具