第一个 node addons --- node cpp addons 插件学习 笔记 01

88 阅读2分钟

前提:

1 电脑已经安装 xcode 2 安装 vscode 并且已经安装 vscode cpp extension 3 安装了 nodejs

# 1 创建目录

npm i -g node-gyp

# 如果是 windows 系统 还要安装 windows-build-tools
npm install --g --production windows-build-tools

touch caddon

npm init -y


项目根目录,创建 binding.gyp 文件

{
    "targets": [
        {
            "target_name": "calculate",
            "sources": ["calculate.cc"]
        },
        {
            "target_name": "hello",
            "sources": ["hello.cc"]
        }
    ]
}

创建 calculate.cc



// hello.cc
#include <node.h>

namespace calculate
{

  using v8::FunctionCallbackInfo;
  using v8::Isolate;
  using v8::Local;
  // using v8::NewStringType;
  using v8::Object;
  // using v8::String;
  using v8::Number;
  using v8::Value;

  void Method(const FunctionCallbackInfo<Value> &args)
  {
    Isolate *isolate = args.GetIsolate();
    int i;
    double x = 100.734, y = 353.2313;
    for (i = 0; i < 1000000000; i++)
    {
      x += y;
    }

    auto total = Number::New(isolate, x);

    args.GetReturnValue().Set(total);
  }

  void Initialize(Local<Object> exports)
  {
    NODE_SET_METHOD(exports, "calc", Method);
  }

  NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)

} // namespace demo

创建 hello.cc

// hello.cc
#include <node.h>

namespace demo {

using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::NewStringType;
using v8::Object;
using v8::String;
using v8::Value;

void Method(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  args.GetReturnValue().Set(String::NewFromUtf8(
      isolate, "world", NewStringType::kNormal).ToLocalChecked());
}

void Initialize(Local<Object> exports) {
  NODE_SET_METHOD(exports, "hello", Method);
}

NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)

}  // namespace demo

此时一定会有 #include <node.h> 所在的行一定会报错

需要找到 node.h 所在的目录

➜  caddon which node
/Users/x/.nvm/versions/node/v22.11.0/bin/node

# 头文件目录所在的目录 如果当前 node 版本号不一样,和这个笔记里面的不一样,改一下就好不要照抄
# /Users/x/.nvm/versions/node/v22.11.0/include/node/**

image.png

image.png

把上面找到的 node.h 头文件所在的路径添加到如图所示的位置,就可以解决红线报错问题了

image.png

接下来解决 cpp 编译的配置参数,点击运行按钮

image.png

会生成如下配置文件 .vscode/tasks.json

image.png

在里面添加 所使用的 cpp 标准版本 "-std=c++17", 和 编译当前目录下的所有 .cc .cpp 文件 "${fileDirname}/{**.cc,**.cpp,**.c}",

            "args": [
                "-fcolor-diagnostics",
                "-fansi-escape-codes",
                "-std=c++17",
                "-g",
                "${fileDirname}/{**.cc,**.cpp,**.c}",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}"
            ],

默认的配置文件长这样

            "args": [
                "-fcolor-diagnostics",
                "-fansi-escape-codes",
                "-g",
                "${file}",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}"
            ],

主要改动如下图: image.png

package.json

{
  "name": "caddon",
  "version": "1.0.0",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": ""
}

看表面意思是配置一下


node-gyp configure

编译


node-gyp build

编译完以后会在 项目里多出 calculate.node hello.node 两个产物

image.png

接着就可以在 nodejs 里面调用了,代码如下:

const calculate = require('./build/Release/calculate')


console.log('-----ftf----: ', calculate.calc())

输出如下:

image.png

笔记记录一下过程,并没有深入设计 js 和 cpp 的数据传递,但是知道了怎么 写和跑 node addon,算是 node addon 的入门 hello worl的记录吧

www.bilibili.com/video/BV1vV…

nodejs.org/api/addons.…