addon其实就是一个桥梁,利用V8提供的API,可以实现JavaScript和C++的互相调用,打通JavaScript和C++之间的接口。
我们先编写一个小例子,大概了解js层和addon之间数据交换的过程。需要三个文件:
- binding.gyp:其实就是一个json文件,因为要使用node-gyp进行编译,该文件可以说是定义了一些编译规则。
- addon.cc: 该文件就是我们需要编写的addon,node-gyp借助vs编译后最终会生成
addon.node二进制文件。 - index.js: 该文件就是测试js,在js层可以加载addon,调用addon对外的函数。
安装nan模块
npm install nan
binding.gyp文件具体内容:
{
'targets': [
{
"target_name": "addon",
"sources": ["./addon.cc"],
"include_dirs": [
"<!(node -e \"require('nan')\")",
],
}
]
}
参数说明:
1."addon – addon.cc最终编译成addon的文件名
2. baddon.cc – 需要编译的c文件
3. “<!(node -e “require(‘nan’)”)” – 因为使用的是NAN api的方式要加载nan模块。
addon.cc 文件内容如下:
#include <iostream>
#include <string>
#include <v8.h>
#include <nan.h>
using namespace v8;
NAN_METHOD(bjcast_session)
{
Local<String> ip_value = Local<String>::Cast(info[0]);
String::Utf8Value ip(ip_value); //从js获取的String类型转换成v8的字符串类型
char *ip_str = *ip; //转换成c++的类型,可以作为参数传递到c++底层
Local<Number> port_value = Local<Number>::Cast(info[1]);
int port = port_value->NumberValue(); //从js层获取的umber类型转换成v8 int类型
std::cout << "addon receive ip value is " << ip_str << ", port is " << port << std::endl;
//从js层获取的Function类型转换成v8的函数类型
Nan::Callback *start_session_callback = new Nan::Callback(info[2].As<Function>());
//把js层获取到参数传递到c++底层
// int32_t value = BJCastProjectLib::GetInstance().StartBJCastSession(
// ip_str, (uint16_t)port, start_session_callback);
//一般返回到js层的value值都是在addon中调用底层的c++ dll返回的值。
int value = 5;
std::string name = "中国";
Local<Value> argv[] = {Nan::New(name).ToLocalChecked()}; //把需要返回给js层的数据根据v8的一些规则做处理
start_session_callback->Call(1, argv); //通过回调函数把数据返回到js层
info.GetReturnValue().Set(Nan::New((int)value)); //js调用startBJCastSession函数的返回值
}
//初始化模块,startBJCastSession就是提供给js层的函数,bjcast_session就是上面我们写的函数,
//js层调用startBJCastSession,其实就是间接的调用了bjcast_session函数
NAN_MODULE_INIT(init)
{
Nan::Export(target, "startBJCastSession", bjcast_session);
}
NODE_MODULE(bjcast_project_addon_win, init)
我们通过node-gyp rebuild命令编译成功后会在build -> Release文件夹中生成一个bjcast_project_addon.node文件
index.js文件内容为:
var BJLib = require('./build/Release/addon.node'); //加载node模块
//console.log(BJLib); //可以打印出来查看BJLib对象有哪些函数
var serverIp = '192.168.9.155'; //String类型参数
var serverPort = 8188; //Number类型参数
var pin = '';
onStartSessionResult = function(result) { //回调函数
console.log('onStartSessionResult callback receive result is ', result);
}
//调用addon中对js层的接口函数
var ret_value = BJLib.startBJCastSession(serverIp, serverPort, onStartSessionResult);
console.log("nodejs receive value is ",ret_value);
运行
node-gyp rebuild
node index.js
6.输出结果为:
addon receive ip value is 192.168.9.155, port value is 8188
onStartSessionResult callback receive result is 中国
nodejs receive value is 5