Skip to content

Latest commit

 

History

History
84 lines (67 loc) · 2.58 KB

210401.md

File metadata and controls

84 lines (67 loc) · 2.58 KB

nodeJS 利用 N-API 编写c++ node扩展

基础

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

环境

  1. node-gyb 8.0.0 支持 Python v3.6, v3.7, v3.8, or v3.9;记住一定要将 python 写到 path 环境变量
  2. node-gyb
npm i node-gyb -g

写 c++ 代码

#include <stdio.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. vscode 报错: #include <node_api.h> 检测到 #include 错误。请更新 includePath,需要在 vscode 中定义 nodeJS 安装地址的引入;
.vscode/c_cpp_properties

{
    "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "${workspaceFolder}/**",
                "C:/Users/{usenaem}/.node-gyp/10.15.2/include/node"
            ],
            ....
        }
    ]
}

编译成 .node 文件并引入

编译

  1. node-gyp configure: 生成初始配置
  2. node-gyp build: 将 c++ 代码生成编译文件
  3. node-gyp rebuild: 将上述两步一起完成

引入 .node

const hello = require('./lib/test.node');
hello.sayHello('ddd'); // 输出 hello