资讯专栏INFORMATION COLUMN

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

魏明 / 566人阅读

摘要:介绍的全称为其表现上是一个包。引用扩展,暴露出方法供上层使用。初次开发扩展的用户需要注意下项目目录中的文件会读取项目中的为表示最后生成的扩展文件名为。累加完成后通过将结果返回出去。

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")"就是利用nodejs的require能力,寻找nan的目录,执行效果如下:

sources项指明了c++扩展需要编译的源文件。

c++部分开发

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

#include 
#include 
#include 
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 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包发布出去

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/100800.html

相关文章

  • vscode调试node.js c++扩展

    摘要:类似的,如果我们想要调试扩展,我们也需要扩展源文件的调试符号信息。配置安装插件这里我们将用来调试扩展。配置输入配置一个任务,该任务会执行,生成带调试信息的扩展文件。 Debugging NodeJS C++ addons using VS Code 之前笔者写了一篇 用NAN写一个nodejs的c++扩展, 实际开发过程中,肯定是有单步调试的需求。这里简单介绍用如何用vscode调试...

    王伟廷 评论0 收藏0
  • memwatch分析

    摘要:介绍是一个扩展,主要用来观察内存泄露问题,基本用法如下实现分析分析的版本为。的入口函数在文件中,通过进行声明。下面分析下函数的具体实现函数内部会递归调用函数得到最终堆快照的结果。回调的触发与的钩子有关,详细看下一节分析。 介绍 memwatch是一个c++扩展,主要用来观察nodejs内存泄露问题,基本用法如下: const memwatch = require(@airbnb/mem...

    worldligang 评论0 收藏0
  • 支持多户web终端实现及安全保障(nodejs

    摘要:每次在命令行中输入一串命令,敲入回车,终端进程都会一个子进程,用来执行输入的命令,终端进程通过系统调用监听子进程退出,同时通过暴露的输出子进程执行信息。父进程通过创建该的实现向子进程从设备的输入输出。 背景 terminal(命令行)作为本地IDE普遍拥有的功能,对项目的git操作以及文件操作有着非常强大的支持。对于WebIDE,在没有web伪终端的情况下,仅仅提供封装的命令行接口是完...

    kaka 评论0 收藏0
  • 在 V8 中从 JavaScript 到 C++ 类型转换

    摘要:本文转载自众成翻译译者乱发小生链接原文学习怎样传递信息从到是一个非常难的事情。原因在于和两种语言类型之间的巨大差异。你可以在这里查看所有的类型。这两个组件松散和严格的表明一系列函数接收不同类型的参数,,,和和它们的返回值。 本文转载自:众成翻译译者:乱发小生链接:http://www.zcfy.cc/article/3360原文:https://nodeaddons.com/type-...

    betacat 评论0 收藏0
  • Node.js 是什么?我为什么选择它?

    摘要:单线程使用单线程来运行,而不是向之类的其它服务器,每个请求将生产一个线程,这种方法避免了上下文切换和内存中的大量执行堆栈,这也是和其它服务器为解决上一个年,著名的并发连接问题而采用的方法。 showImg(https://segmentfault.com/img/remote/1460000019968794?w=1080&h=675);当我们学习一项新的事物的时候,我们首先要知道它来...

    Joyven 评论0 收藏0

发表评论

0条评论

魏明

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<