使用napi node_使用Napi / node-addon-api和Cmake的独立于Node.js版本的C ++ Native Addon

邹丰羽
2023-12-01

使用napi node

This is a tutorial for c++ Node-addon-api / Napi addon using cmake.Napi makes it independent of node.js version, means our addon will be compatible with all future version of node.js . Cmake is a cross-platform code compiling tool for c++ code this makes us independent of complex node-gyp process.

这是一个使用cmake的c ++ Node-addon-api / Napi插件教程.Napi使它独立于node.js版本,这意味着我们的插件将与所有以后的node.js版本兼容。 Cmake是用于C ++代码的跨平台代码编译工具,它使我们独立于复杂的node-gyp进程。

要求 :- (Requirements :-)

  1. install Node.js > 10.x

    安装Node.js > 10.x

Note:- Remember to check automatically install the necessary tools.(this will be required to install vs-build tool on windows )

注意:-请记住要检查是否自动安装了必要的工具。(在Windows上安装vs-build工具将需要此工具)

2. install Cmake > 3.15

2. 安装Cmake > 3.15

概述- (Overview -)

  1. Napi addon require four major part

    Napi插件需要四个主要部分
  • package.json file- to handle dependencies, names, version, installation commands etc.

    package.json文件-处理依赖关系,名称,版本,安装命令等。
  • CMakeLists.txt file- commands to needed to compile c++ code.

    CMakeLists.txt文件-编译c ++代码所需的命令。
  • A node script - to use native addon.

    节点脚本-使用本机插件。
  • C++ source files

    C ++源文件

2. Addon will be OS dependent, so if you want to make it cross-platform compatible. Then it will be needed to built(once) on all platforms separately.

2. Addon将取决于操作系统,因此,如果要使其跨平台兼容。 然后,需要分别在所有平台上构建(一次)。

Node.js应用程序(package.json) (Node.js app (package.json))

  1. Make a directory for your project and open terminal/power-shell in it.

    为您的项目创建一个目录,并在其中打开终端/电源外壳。
  2. Since node.js is installed already we will create a project(package.json) using npm.

    由于已经安装了node.js,我们将使用npm创建一个项目(package.json)。
npm init

This will ask you package name, version, description, etc. Enter accordingly or just press enter until it’s done with defaults.

这将询问您软件包的名称,版本,说明等。进行相应输入或按Enter直到完成默认设置。

安装npm软件包 (Install npm Packages)

  1. install node-addon-api / napi package for node.js addon

    为node.js插件安装node-addon-api / napi软件包

npm install node-addon-api --save

2. install cmake.js package for Cmake handling

2.安装cmake.js软件包以进行Cmake处理

npm install cmake-js --save-dev

C ++源代码 (C++ source code)

We will be using a simple program which takes two argument and print their sum. (If you want to run multi-threaded code with filesystem head over to end of article)

我们将使用一个简单的程序,该程序带有两个参数并打印其和。 (如果要使用文件系统运行到文章末尾运行多线程代码)

  • Now lets use Napi syntex to export this c++ function to node-js.

    现在让我们使用Napi syntex将此c ++函数导出到node-js。
  1. Create a source directory for your c++ files named src

    为名为src c ++文件创建源目录

  2. Create a c++ header file in that directory named as src/example.h and add below code in it.

    在该目录中创建一个名为src/example.h的c ++头文件,并在其中添加以下代码。

#include <napi.h>
#include <iostream>
using namespace std;namespace example{
//add number function
int add(int x, int y);//add function wrapper
Napi::Number addWrapped(const Napi::CallbackInfo& info); //Export API
Napi::Object Init(Napi::Env env, Napi::Object exports);
NODE_API_MODULE(addon, Init)
}
  • napi.h is a header file for node-addon-api .

    napi.h是node-addon-api的头文件。
  • Then we are declaring c++ function and Its wrapper which will call c++ function for us whenever wrapper will be called from node-js.

    然后,我们声明c ++函数及其包装器,只要从node-js调用包装器,它就会为我们调用c ++函数。
  • Last two line export functions name to nodejs and register addon in nodejs.

    最后两行导出函数名称为nodejs,并在nodejs中注册插件。

3. Create a c++ source file in src directory named as src/example.cpp and add below code in it.

3.在src目录中创建一个名为src/example.cpp的c ++源文件,并在其中添加以下代码。

#include "example.h"using namespace std;int example::add(int x, int y){
return (x+y);
}
Napi::Number example::addWrapped(const Napi::CallbackInfo& info){
Napi::Env env = info.Env();
//check if arguments are integer only.
if(info.Length()<2 || !info[0].IsNumber() || !info[1].IsNumber()){
Napi::TypeError::New(env, "arg1::Number, arg2::Number expected").ThrowAsJavaScriptException();
}
//convert javascripts datatype to c++
Napi::Number first = info[0].As<Napi::Number>();
Napi::Number second = info[1].As<Napi::Number>();
//run c++ function return value and return it in javascript
Napi::Number returnValue = Napi::Number::New(env, example::add(first.Int32Value(), second.Int32Value()));
return returnValue;
}
Napi::Object example::Init(Napi::Env env, Napi::Object exports)
{
//export Napi function
exports.Set("add", Napi::Function::New(env, example::addWrapped)); return exports;
}
  • Call example.h header file.

    调用example.h头文件。
  • write definition of c++ function.

    编写c ++函数的定义。
  • write definition of wrapper validate arguments and convert them to c++ datatype.

    写包装器验证参数的定义,并将其转换为c ++数据类型。
  • wrapper will call c++ function with argument and return result.

    包装器将使用参数调用c ++函数并返回结果。
  • last function export wrapper function to node-js.

    最后一个函数将包装函数导出到node-js。

CMake配置(CMakeLists.txt) (CMake configuration (CMakeLists.txt))

CMakeLists.txt: this file will contain all configuration and command required by cmake to compile c++ code.

CMakeLists.txt:此文件将包含cmake编译c ++代码所需的所有配置和命令。

  1. Create a file in project directory named as CMakeLists.txt and add below code in it.

    项目目录中创建一个名为CMakeLists.txt的文件并在其中添加以下代码。

cmake_minimum_required(VERSION 3.15)# Name of the project (will be the name of the plugin)project (addon)set(CMAKE_CXX_STANDARD 17)# Don't add this line if you will try_compile with boost.set(CMAKE_CXX_STANDARD_REQUIRED ON)# Essential include files to build a node addon,
# you should add this line in every CMake.js based project.include_directories(${CMAKE_JS_INC})# Declare the location of the source filesfile(GLOB SOURCE_FILES "src/*.cpp" "src/*.h")# This line will tell CMake that we're building a shared library
# from the above source files
# named after the project's nameadd_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${CMAKE_JS_SRC})# This line will give our library file a .node extension without any "lib" prefixset_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node")# Essential library files to link to a node addon,
# you should add this line in every CMake.js based project.target_link_libraries(${PROJECT_NAME} ${CMAKE_JS_LIB})# Include N-API wrappersexecute_process(COMMAND node -p "require('node-addon-api').include"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE NODE_ADDON_API_DIR
)
string(REPLACE "\n" "" NODE_ADDON_API_DIR ${NODE_ADDON_API_DIR})
string(REPLACE "\"" "" NODE_ADDON_API_DIR ${NODE_ADDON_API_DIR})
target_include_directories(${PROJECT_NAME} PRIVATE ${NODE_ADDON_API_DIR})
add_definitions(-DNAPI_VERSION=3)
  • require cmake minimum version.

    要求cmake最低版本。
  • set c++ version (in our case it is c++ 17).

    设置c ++版本(在我们的例子中是c ++ 17)。
  • then some boilerplate to include source files and libraries.

    然后一些样板包括源文件和库。
  • set node-js libraries specially napi.

    专门设置napi来设置node-js库。
  • add napi version

    添加napi版本

为cmake.js配置package.json (Configure package.json for cmake.js)

  1. Add install command in Script field like below code

    在脚本字段中添加安装命令,如以下代码所示
"scripts": {
"install": "cmake-js compile"
},
  • This will trigger Cmake to compile c++ code using CMakeLists.txt file configuration.

    这将触发Cmake使用CMakeLists.txt文件配置来编译c ++代码。
  • Optionally you can pass architecture ia32 or x64 like this:

    (可选)您可以像这样传递ia32或x64体系结构:

"scripts": {
"preinstall": "npm config set cmake_js_arch ia32",
"install": "cmake-js compile"
},

调用C ++函数的节点脚本 (Node script to call c++ functions)

Lastly call c++ function in a node script with argument

最后在带有参数的节点脚本中调用c ++函数

  1. Create a index.js file in project directory and add below code in it.

    在项目目录中创建一个index.js文件,并在其中添加以下代码。
const {add} = require("./build/Release/addon.node");console.log(add(2, 3));
  • Here we are importing addon as a node_module and then call our C++ function form it.

    在这里,我们将插件作为node_module导入,然后从中调用C ++函数。

安装并运行 (Install and Run)

  1. execute both commands from project directory

    从项目目录执行两个命令
npm install
node index
  • First command will compile all c++ files one by one and generates a .node file in build folder.

    第一个命令将一个接一个地编译所有c ++文件,并在build文件夹中生成一个.node文件。
  • Second command will execute node script, which calls c++ function and print output on console.

    第二个命令将执行节点脚本,该脚本调用c ++函数并在控制台上打印输出。

2. Output should look like this:

2.输出应如下所示:

atiq@edit02 napi_example % npm install
>cmake-js compile
[
'/usr/local/bin/node',
'/Users/atiq/Desktop/napi_example/node_modules/.bin/cmake-js',
'compile',
'--arch',
'x64'
]
...
...
...
...
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ - works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
...
...
...
Scanning dependencies of target addon
[ 50%] Building CXX object CMakeFiles/addon.dir/src/example.cpp.o
[100%] Linking CXX shared library Release/addon.node
[100%] Built target addon
npm WARN test@1.0.0 No description
npm WARN test@1.0.0 No repository field.
audited 139 packages in 2.236satiq@edit02 napi_example % node index5

代码库 (Code Repository)

You can access complete code of this project here.

您可以在此处访问该项目的完整代码。

其他可能性 (Additional Possibilities)

  • You can call any C++ header/source file in above c++ code and call their functions.

    您可以在上述c ++代码中调用任何C ++头文件/源文件并调用它们的函数。
  • Multi-thread code can be called in these c++ functions but exception handling must be handled in some way.

    可以在这些c ++函数中调用多线程代码,但是必须以某种方式处理异常处理。
  • Napi has a lot of examples for different concept of c++.

    Napi有很多关于不同c ++概念的示例

  • Native addon can be used with electron, nw.js with two three lines of code.

    原生插件可以与电子nw.js一起使用,两行三行代码。

    Native addon can be used with electron, nw.js with two three lines of code.I have another tutorial for using c++ native addon in electron.js.

    原生插件可以与电子nw.js一起使用,两行三行代码。 我还有另一个关于在electronic.js中使用c ++本地插件的教程

  • You can ask any question in comments below or find me on twitter.

    您可以在下面的评论中提问,也可以在Twitter上找到我。

翻译自: https://medium.com/@gauriatiq/c-native-addon-independent-of-node-js-version-using-napi-node-addon-api-and-cmake-53315582cbd1

使用napi node

 类似资料: