前面一篇介绍了一些基础,现在我们来看看官方的V8接口文档。
我们先来看看简单的hello world例子
#include <node.h> #include <v8.h> using namespace v8; //使用命名空间v8,不用在代码中写v8::XXXX Handle<Value> Method(const Arguments& args) { //定义一个function,返回Handle<Value>类的值 HandleScope scope; //实例化scope,用来存放返回值 return scope.Close(String::New("world")); //将返回值丢入scope.close中 } void init(Handle<Object> target) { //接受参数 Handle<Object>类型,注意,这里target是指针 target->Set(String::NewSymbol("hello"), //调用Set方法,对这个对象增加key和value FunctionTemplate::New(Method)->GetFunction()); //调用类FunctionTemplate的静态成员New方法,传入Handle<Value>类型的Method,然后调用GetFunction方法生成node函数,具体v8参考手册上有说明 } NODE_MODULE(hello, init) //固定将文件名hello,和init初始化函数丢入NODE_MODULE
这个一个模板形式:
一个初始化函数一个node_module
void Initialize (Handle<Object> target); NODE_MODULE(module_name, Initialize)
接下来是第二段例子 add相加的方法:
#define BUILDING_NODE_EXTENSION #include <node.h> using namespace v8; Handle<Value> Add(const Arguments& args) { HandleScope scope; if (args.Length() < 2) { //如果args的长度小于2,则抛出错误,从下面代码我们知道如何抛出一个错误,以后照搬就行 ThrowException(Exception::TypeError(String::New("Wrong number of arguments"))); return scope.Close(Undefined());//返回Udefined } if (!args[0]->IsNumber() || !args[1]->IsNumber()) {//判断2个参数是否是number ThrowException(Exception::TypeError(String::New("Wrong arguments"))); return scope.Close(Undefined()); } Local<Number> num = Number::New(args[0]->NumberValue() + args[1]->NumberValue());//将参数转化成C++可用的double型相加,然后再转化成输出给node的Number型,最后赋值给 Local<Number> 类型的变量 num,返回给用户 return scope.Close(num); } void Init(Handle<Object> target) { target->Set(String::NewSymbol("add"), FunctionTemplate::New(Add)->GetFunction()); } NODE_MODULE(addon, Init)
是不是看到了一些新的内容比如字符串转换String::New("Wrong arguments");把c++字符串转成js字符串
agrs[0]->NumberValue()把js的Number转成C++可用的double
V8接口Local这种类型都是用来将c++的数据传输给js,
V8命名空间下的一些类,比如String,Date都是用来将C++的数据转换成输出给js用的,当然这些类都是继承Value类
感觉模块的工作流程就是这样的的,接受node端的参数,如果要运算则变成C++的数据类型进行运算,然后再将计算完成的数据转化成js的数据类型返回给js端
上面的js调用:
var addon = require(‘./build/Release/addon‘); console.log( ‘This should be eight:‘, addon.add(3,5) );
下面继续看例子:
实现一个js的回调函数参数为hello world
#define BUILDING_NODE_EXTENSION #include <node.h> using namespace v8; Handle<Value> RunCallback(const Arguments& args) { HandleScope scope; Local<Function> cb = Local<Function>::Cast(args[0]); //将参数第一个也就是js传递过来的回调函数转化成c++的function const unsigned argc = 1; //定义无符号int argc为1 Local<Value> argv[argc] = { Local<Value>::New(String::New("hello world")) };//创建一个数组,长度为1, cb->Call(Context::GetCurrent()->Global(), argc, argv);//利用local<function>的call方法然后将上下文,参数长度,以及参数数组传入call方法,即调用js端的回调 return scope.Close(Undefined()); //返回undeined,无返回值 } void Init(Handle<Object> target) { target->Set(String::NewSymbol("runCallback"), FunctionTemplate::New(RunCallback)->GetFunction()); } NODE_MODULE(addon, Init)
js端调用代码:
var addon = require(‘./build/Release/addon‘); addon.runCallback(function(msg){ console.log(msg); // ‘hello world‘ });