用C/C++来实现 Node.js 的模块(二)_node.js(2)
// 具体参考 v8 文档
// http://izs.me/v8-docs/classv8_1_1Value.html#a6eac2b07dced58f1761bbfd53bf0e366)
// 的 `NumberValue` 函数
Local<Number> num = Number::New(args[0]->NumberValue() + args[1]->NumberValue());
return scope.Close(num);
}
函数大功告成!
最后把尾部的导出函数给写好就 OK 了。
void Init(Handle<Object> exports)
{
exports->Set(String::NewSymbol("add"),
FunctionTemplate::New(Add)->GetFunction());
}
NODE_MODULE(addon, Init)
等你编译好之后,我们就能这样用了:
console.log(addon.add(1, 1) + "b");
你会看到一个 2b !✧。٩(ˊᗜˋ)و✧*。
回调函数
上一章我们只讲了个 Hello world,这一章阿婆主就良心发现一下,再来个回调函数的写法。
惯例我们先写好框架:
#include <node.h>
using namespace v8;
Handle<Value> RunCallback(const Arguments& args)
{
HandleScope scope;
// ... 噼里啪啦噼里啪啦
return scope.Close(Undefined());
}
然后我们决定它的用法是这样的:
func(function(msg) {
console.log(msg);
});
即它会给回调函数传入一个参数,我们设想它是一个字符串,然后我们可以 console.log() 出来看。
首先你要有一个字符串系列
废话不多说,先给它一个字符串喂饱了再说吧。(√ ζ ε:)
不过我们得让这个字符串是通用类型的,因为 Node.js 代码是弱类型的。
Local<Value>::New(String::New("hello world"));
什么?你问我什么是 Local<Value>?
那我稍稍讲一下吧,参考自这里和V8参考文档。
如文档所示,Local<T> 实际上继承自 Handle<T>,我记得上一章已经讲过 Handle<T> 这个东西了。
然后下面就是讲 Local 了。
Handle 有两种类型, Local Handle 和 Persistent Handle ,类型分别是 Local<T> : Handle<T> 和 Persistent<T> : Handle<T> ,前者和 Handle<T> 没有区别生存周期都在 scope 内。而后者的生命周期脱离 scope ,你需要手动调用 Persistent::Dispose 结束其生命周期。也就是说 Local Handle 相当于在 C++`在栈上分配对象而 Persistent Handle 相当于 C++ 在堆上分配对象。
然后你要有个参数表系列
终端命令行调用 C/C++ 之后怎么取命令行参数?
#include <stdio.h>
void main(int argc, char* argv[])
{
// ...
}
对了,这里的 argc 就是命令行参数个数,argv[] 就是各个参数了。那么调用 Node.js 的回调函数,v8 也采用了类似的方法:
int argc,
Handle<Value> argv[]
);
~~QAQ 卡在了 Handle<Object> recv 了!!!明天继续写。~~
好吧,新的一天开始了我感觉我充满了力量。(∩^o^)⊃━☆゚.*・。
经过我多方面求证(SegmentFault和StackOverflow以及一个扣扣群),终于解决了上面这个函数仨参数的意思。