node.js 与 C/C++ 数据互通
node.js 与 C/C++ 数据互通
一、首先了解下node.js 模块的编译。
.js 文件,是fs模块同步读取文件后编译执行。
.node文件,C/C++ 编写的拓展文件,通过dlopen() 方法加载最后编译生产的文件。
.json文件 通过fs模块同步读取数据,用JSON.parse()解析返回结果。
其余拓展文件,都被当作.js文件载入。
二、.node文件的生成
- 拓展文件的编译和加载在不同平台上也不尽相同,下图展示
windows平台编译加载过程
graph TD
C/C++源码 --> VC++
VC++ --编译源码--> .dll文件
.dll文件 --生成.node文件--> 加载.dll文件
加载.dll文件 --dlopen加载--> 导出给javaScript
三、编译条件
.net framework 4.5 +windows-bulid-tools和VS2017 & python2.7(3.x不支持),只需安装其中一个,博主使用的windows-bulid-toolsnpm install -g windows-bulid-toolsnode-gyp:用于编译原生C++ 模块npm install -g node-gypbindings:非必须条件,该模块可检查.node的位置node-addon-api: 实现C++ 插件有三种选择:N-API、nan、或直接使用V8、libuv和node.js库;node-addon-api:是对N-API的封装,不仅简化了N-API的使用,同时也保留了N-API的优点。
四、示例
-
创建项目
mkdir node
cd addon
npm init
npm i node-addon-api bindings -S
-
新建编写
node/grade.h#include <iostream> /*** 声明 grade 类,包含静态成员函数judeg。博主C++写的不好,多多包涵。 **/ class grade { public: static char* judge(float grade){ if(grade<60){ return "bad!"; } return "good!"; } };node/addon.cc//napi.h 是node-addon-api 的头文件。里面封装了 N-API的头文件 #include <napi.h> #include <iostream> //引入自定义 grade 类的头文件 #include <grade.h> //明明空间 Napi using namespace Napi; // info 是 javaScript 传入的参数 Napi::String result(const CallbackInfo& info){ // 将javaScript 转为N-API 的类型,将N-API 类型转为C++类型 float grade = info[0].As<Number>().ToNumber().FloatValue(); // grade::judge(grade) 调用自定义C++ 函数,返回 char* 类型 // 将char* 类型转为N-API 的 String 类型 return String::New(info.Env(), grade::judge(grade)); } Napi::Object Init(Env env,Object exports){ /*** 导出 将 result函数以 result 命名导出 如下,可以导出n条所需函数: exports.Set("a",Function::New(env,b)) exports.Set("c",Function::New(env,d)) */ exports.Set("result",Function::New(env,result)); return exports; } // napi的句柄,无需改动 NODE_API_MODULE(addon, Init);node/binding.gyp{ "targets": [ { "target_name": "addon",//导出的模块名称 "sources": [ "addon.cc",//源文件 ], "include_dirs": [ "<!@(node -p \"require('node-addon-api').include\")", //使用到的源文件 "./" ], "libraries": [], "dependencies": [ "<!(node -p \"require('node-addon-api').gyp\")" ], "cflags!": ["-fno-exceptions"], "cflags_cc!": ["-fno-exceptions"], "defines": ["NAPI_CPP_EXCEPTIONS"], "xcode_settings": { "GCC_ENABLE_CPP_EXCEPTIONS": "YES" } } ] } -
执行npm i 或者 node-gyp rebuild控制台编译成功后,生成build 文件,bulid/Release/addon.node文件
![]()
-
创建
node/app.jsconst addon = require('bindings')('addon'); console.log(addon.result(90));执行
node app.js控制台输出 good!![]()
-
总结
转化流程可以粗略用以下流程展示
graph LR javaScript --类型转化--- N-API N-API --类型转化--- C/C++ -
示例代码见 gitHub: https://github.com/zcookies/addon



浙公网安备 33010602011771号