nodejs v8 新特性——利用N-API编写c++ node扩展

相信为nodejs写过 c++扩展的人,都有过nodejs版本升级之后c++需要重新编译的惨痛经历。nodejs v8.0之后node官方推出了N-API 大大的解决了这一问题。

N-API 是独立于v8引擎之外的模块。用来向c++扩展程序提供接口,从而达到了c++扩展程序和v8引擎的隔离。因此在当nodejs版本变化之后c++扩展程序无需重新编译也能运行。

下面我们来看如何利用N-API为nodejs写一个简单的扩展:

环境

首先已经确认你的环境已经可以编译c++程序。
例如 python , make , gcc 等等。

我们的例子只从nodejs方面讲起。nodejs版本为8.x 。
首先安装 node-gyp 用来编译我们的扩展程序

npm install -g node-gyp

编写扩展程序

  1. 创建文件建 hello
  2. 在hello目录下创建hello.cc
  3. 在hello.cc 中编写如下代码并保存。
// 首先要引用 node_api.h
#include <node_api.h>

// 定义native方法 SayHello 打印一个字符串"Hello"
napi_value SayHello(napi_env env, napi_callback_info info) {
  printf("Hello\n");
  return nullptr;
}

// 如果把hello.cc看做js文件,则Init 方法的作用就是初始化当前module。
// 但是Init方法不能修改module,只能修改module的exports。
// env :当前javascript的上下文文件
// exports : 即可看做当前文件的model.exports,初始化之前是一个空对象。
napi_value Init(napi_env env, napi_value exports) {
  napi_status status;
  napi_value fn;

// 将上面的SayHello 方法生成一个可供javascript调用的napi_value对象。
// 并且赋值给指针 fn。
// status 为是否生成成功的状态值 ,若成功则值为 napi_ok。
  status =  napi_create_function(env, nullptr, 0, SayHello, nullptr, &fn);
  if (status != napi_ok) return nullptr;

// 将刚才生成的javascript 对象方法fn 添加到exports中,属性名为sayHello
// 翻译为javascript代码为:exports.sayHello = fn;
  status = napi_set_named_property(env, exports, "sayHello", fn);
  if (status != napi_ok) return nullptr;

 // 后将exports 返回 完成module的初始化
  return exports;
}

// 注册当前module
NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)

编译扩展程序

  1. 创建文件 binding.gyp
  2. 在binding.gyp 中写入如下描述并保存。
{
  "targets": [
    {
      "target_name": "hello",
      "sources": [ "./hello.cc" ]
    }
  ]
}
  1. 运行 node-gyp rebuild 进行编译

调用刚才写好的扩展程序

  1. 创建app.js 并写入下面的代码。
var addon = require("../build/Release/hello");
addon.hello();

  1. 运行 node app.js 会输出如下信息。
Hello
(node:42630) Warning: N-API is an experimental feature and could change at any time.

注:N-API还在试验阶段api变动会比较大。所以会输出一个Warning。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。