用NAN寫一個nodejs的c++擴展

NAN介紹

NAN的全稱爲Native Abstraction for Node.js, 其表現上是一個Node.js包。安裝後,就獲得一堆C++頭文件,裏面是一堆宏。它主要爲Node.js和V8跨版本提供了封裝的宏,使得開發者不用關心各個版本之間的API的差別。(from 《nodejs來一打C++擴展》)node

NAN的優點在於能夠屏蔽不一樣版本Node的API,使得C++擴展能夠wirte once, compile anywhere,一份C++擴展能夠適用於不一樣版本的Node.js。這裏的c++擴展實現的功能是一個求和的擴展(hello world太多了,寫個不同的)c++

擴展地址爲:www.npmjs.com/package/sum…git

項目代碼地址:github.com/warjiang/de…github

使用方式以下: npm

image

項目目錄以下:

image
在開發以前咱們首先須要安裝nan包( npm install nan -S)。擴展開發分紅兩個層面,c++層面和JS層面。src目錄中主要是c++代碼,也是擴展的實現部分。index.js引用c++擴展,暴露出方法供上層使用。 初次開發nodejs擴展的用戶須要注意下項目目錄中的binding.gyp文件(node-gyp會讀取項目中的binding.gyp):
image
target_name爲sum,表示最後生成的擴展文件名爲 sum.node。include_dirs表示除了nodejs基礎的依賴以外,咱們還須要nan的頭文件, <!(node -e \"require('nan')\")<!表示後面是命令, node -e "require('nan')"就是利用nodejs的require能力,尋找nan的目錄,執行效果以下:
image
sources項指明瞭c++擴展須要編譯的源文件。

c++部分開發

先直接上代碼(src/init.cc):json

#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,暴露出來方法給外部進行調用。bash

js部分開發

有了上面的鋪墊,這裏咱們開發js部分就顯得十分天然。直接上代碼函數

const addon = require('./build/Release/sum')
module.exports = addon.sum
複製代碼

一共就兩行代碼,邏輯清晰簡單,就引用編譯好的擴展,將sum方法暴露出去。ui

發佈

nodejs擴展發佈的時候須要在package.json的scripts部分增長install鉤子的處理,以下:

image
用戶安裝擴展的時候,會在install的鉤子上,幫助用戶執行 node-gyp rebuild來在用戶的機器上生成對應的擴展文件。這樣咱們的開發就完畢了,執行 npm publish將npm包發佈出去
相關文章
相關標籤/搜索