Node.js Native Addons All In One
Node.js Native Addons All In One
Node.js Native Addons/Node.js 原生扩展插件, 是指用C / C++等底层语言编写的模块,然后通过 Node.js 提供的接口编译成可被 JavaScript 直接调用的扩展插件。
C++ Addons
Addons are dynamically-linked shared objects that can be loaded via the require() function as ordinary Node.js modules.
Addons provide a foreign function interface between JavaScript and native code.
There are three options for implementing addons:
Node-API(recommended ✅)nan(Native Abstractions for Node.js)- direct use of internal V8, libuv, and Node.js libraries
https://nodejs.org/api/addons.html
Node-API
Node-API(原名 N-API)是一个用于构建原生插件的 API。它独立于底层 JavaScript 运行时(例如 V8),并作为 Node.js 的一部分进行维护。
该 API 将在各个 Node.js 版本之间保持应用程序二进制接口 (ABI) 的稳定性。
其目的是使插件免受底层 JavaScript 引擎变更的影响,并允许为某一主要版本编译的模块无需重新编译即可在后续的 Node.js 主要版本上运行。ABI 稳定性指南提供了更详细的解释。
https://nodejs.org/api/n-api.html
Node-API is a stable C API built into Node.js that lets C/C++ code create, read, and manipulate JavaScript values as if they were created by JavaScript itself.
It was introduced experimentally in Node.js 8.0.0 and became stable (no longer behind a flag) in the Node.js 8/10 timeframe.
Because Node-API is part of Node.js itself, it requires no additional installation.


https://nodejs.org/learn/node-api
https://nodejs.org/zh-cn/learn/node-api
Node-API 的一个重要搭档是 npm 包 node-addon-api。
它将 C API 封装在一个符合 C++ 惯用语的 C++ 对象模型中,减少了样板代码,并使一些常见模式(例如将 C++ 对象封装成 JavaScript 对象)更加符合人体工程学。
它保留了 Node-API 的全部 ABI 稳定性保证。
$ npm i node-addon-api
https://www.npmjs.com/package/node-addon-api
https://github.com/nodejs/node-addon-api
NAN
Native Abstractions for Node.js / Node.js 的原生抽象
demos
// the equivalent of the following JavaScript code
module.exports.hello = () => 'world';
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);
}
// N.B.: no semi-colon, this is not a function
NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)
}
// namespace demo
Makefile, hello.cc => > hello.node
NODEJS_DEV_ROOT ?= $(shell dirname "$(command -v node)")/..
CXXFLAGS = -std=c++23 -I$(NODEJS_DEV_ROOT)/include/node -fPIC -shared -Wl,-undefined,dynamic_lookup
# target source
hello.node: hello.cc
$(CXX) $(CXXFLAGS) -o $@ $<
$ make
$ node -p 'require("./hello.node").hello()'
# world
(🐞 反爬虫测试!打击盗版⚠️)如果你看到这个信息, 说明这是一篇剽窃的文章,请访问 https://www.cnblogs.com/xgqfrms/ 查看原创文章!
.cpp vs .cc
.cpp 和 .cc 本质上没有语言层面的区别,只是 C++ 源文件的不同命名习惯。

- C Plus Plus, .cpp
- Google C++ Style Guide, .cc
$ g++ main.cpp
# or
$ g++ main.cc
CMake

C files → compiled with C compiler (e.g. gcc)
C++ files → compiled with C++ compiler (e.g. g++ / clang++)
node-gyp
https://www.npmjs.com/package/node-gyp
https://nodejs.org/learn/node-api/build-tools/node-gyp
fibonacci.cc
// The pure C++ function - fast, unmanaged, no JavaScript awareness.
int Fibonacci(int n) {
if (n < 2) return n;
return Fibonacci(n - 1) + Fibonacci(n - 2);
}
// The Bridge Function - This is where N-API works its art.
// It translates JavaScript arguments into C++ types, calls the function,
// and translates the C++ result back into a JavaScript value.
Napi::Value CalculateFibonacci(const Napi::CallbackInfo& info) {
// The Napi::Env is our connection to the JavaScript world.
Napi::Env env = info.Env();
// 1. Validate the number of arguments
if (info.Length() < 1) {
Napi::TypeError::New(env, "Wrong number of arguments")
.ThrowAsJavaScriptException();
return env.Null();
}
// 2. Validate and convert the first argument to a C++ integer
if (!info[0].IsNumber()) {
Napi::TypeError::New(env, "Number expected").ThrowAsJavaScriptException();
return env.Null();
}
int n = info[0].As<Napi::Number>().Int32Value();
// 3. Call our pure C++ function
int result = Fibonacci(n);
// 4. Convert the C++ integer back to a JavaScript Number and return it.
return Napi::Number::New(env, result);
}
// The Init function - This is the entry point, called when the module is required.
// It defines what we expose to the JavaScript world.
Napi::Object Init(Napi::Env env, Napi::Object exports) {
// Set the "calculate" property of the `exports` object to our bridge function.
exports.Set(Napi::String::New(env, "calculate"),
Napi::Function::New(env, CalculateFibonacci));
return exports;
}
// This macro declares the entry point for the Node.js module.
NODE_API_MODULE(fibonacci, Init)
refs


©xgqfrms 2012-2021
www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!
原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!
本文首发于博客园,作者:xgqfrms,原文链接:https://www.cnblogs.com/xgqfrms/p/21008058
未经授权禁止转载,违者必究!

浙公网安备 33010602011771号