1.使用方法
1.1 hello world
#include <node.h>
namespace demo {
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
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"));
}
//初始化函數(shù)
void init(Local<Object> exports) {
//導(dǎo)出Method方法,重命名為hello
NODE_SET_METHOD(exports,"hello",Method);
}
//模塊名為addon
NODE_MODULE(addon, init)
}
要把一個(gè)函數(shù)作為接口導(dǎo)出,需要:
1.為函數(shù)傳入FunctionCallbackInfo<Value>類型的參數(shù)列表夺巩,這個(gè)參數(shù)列表是一個(gè)指針數(shù)組勘高,可以通過(guò)args[index]來(lái)訪問(wèn)每一個(gè)傳入?yún)?shù)菱涤,通過(guò)args[index]->ToString來(lái)調(diào)用參數(shù)對(duì)應(yīng)的方法
2.在函數(shù)中創(chuàng)建一個(gè)js的數(shù)據(jù)類型都要通過(guò)
Isolate* isolate = args.GetIsolate()
這個(gè)隔離對(duì)象指針來(lái)創(chuàng)建,例如:
//創(chuàng)建基本數(shù)據(jù)類型并賦給一個(gè)本地變量
String::NewFromUtf8(isolate,"msg");
Local<Number> num=Number::New(isolate,value);
//創(chuàng)建一個(gè)object
Local<Object> obj=Object::New(isolate);
//讀取一個(gè)回調(diào)函數(shù)
Local<Function> cb = Local<Function>::Cast(args[0]);
3.為函數(shù)創(chuàng)建返回值级野,函數(shù)的返回值必須時(shí)v8的變量類型
args.GetReturnValue().Set(String::NewFromUtf8(isolate, "world"));
4.需要?jiǎng)?chuàng)建一個(gè)初始化函數(shù),函數(shù)的第一個(gè)參數(shù)為module.exports粹胯,第二個(gè)參數(shù)為module蓖柔,可以選擇是同NODE_SET_METHOD宏來(lái)為module.exports添加導(dǎo)出的屬性,也可以在module對(duì)象上完全重寫exports屬性
NODE_SET_METHOD(exports,"hello",Method);
5.最后风纠,使用NODE_MODULE宏指定模塊名和初始化函數(shù)况鸣,即可導(dǎo)出一個(gè)函數(shù)在js中調(diào)用
1.2 函數(shù)的參數(shù)
讀取傳入?yún)?shù)和返回結(jié)果需要在js數(shù)據(jù)類型和C++數(shù)據(jù)類型之間做轉(zhuǎn)換,讀取并轉(zhuǎn)化為C++數(shù)據(jù)類型竹观,即可通過(guò)C++進(jìn)行計(jì)算
ars[0]->NumberValue(); //轉(zhuǎn)化為number
args[1]->ToString(); //轉(zhuǎn)化為string
1.3 導(dǎo)出對(duì)象
#ifndef MYOBJECT_H
#define MYOBJECT_H
#include <node.h>
#include <node_object_wrap.h>
namespace demo
{
class MyObject: public node::ObjectWrap
{
public:
static void Init(v8::Local<v8::Object> exports);
private:
explicit MyObject(double value = 0);
~MyObject();
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);
static v8::Persistent<v8::Function> constructor;
double value_;
};
}//namespace demo
#endif
#include "myobject.h"
namespace demo {
using namespace v8;
Persistent<v8::Function> MyObject::constructor;
//初始化函數(shù)
void MyObject::Init(v8::Local<v8::Object> exports)
{
Isolate* isolate = exports->GetIsolate();
//創(chuàng)建構(gòu)造函數(shù)
Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New);
tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject"));
tpl->InstanceTemplate()->SetInternalFieldCount(1);
//在原型上添加方法
NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne);
//設(shè)置構(gòu)造函數(shù)
constructor.Reset(isolate, tpl->GetFunction());
exports->Set(String::NewFromUtf8(isolate, "MyObject"), tpl->GetFunction());
}
MyObject::MyObject(double value)
:value_(value)
{
}
MyObject::~MyObject()
{
}
//v8構(gòu)造函數(shù)
void MyObject::New(const v8::FunctionCallbackInfo<v8::Value>& args)
{
Isolate* isolate = args.GetIsolate();
//構(gòu)造函數(shù)調(diào)用
if (args.IsConstructCall())
{
double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
MyObject* obj = new MyObject(value);
//this指向這個(gè)對(duì)象
obj->Wrap(args.This());
args.GetReturnValue().Set(args.This());
}
else {
//否則調(diào)用v8構(gòu)造函數(shù)镐捧,讀取參數(shù)放入?yún)?shù)列表
const int argc = 1;
Local<Value> argv[argc] = { args[0] };
Local<Context> context = isolate->GetCurrentContext();
Local<Function> cons = Local<Function>::New(isolate, constructor);
Local<Object> result = cons->NewInstance(context, argc, argv).ToLocalChecked();
args.GetReturnValue().Set(result);
}
}
//將成員變量加一
void MyObject::PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args)
{
Isolate* isolate = args.GetIsolate();
MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder());
obj->value_ += 1;
args.GetReturnValue().Set(Number::New(isolate, obj->value_));
}
}//namespace demo