扩展插件(Addons)是动态链接的共享对象,这些对象提供了使用C/C++类库的能力。由于涉及了多个类库导致了这类API目前比较繁杂,主要包括下述几个主要类库:
V8 JavaScript,C++类库,作为JavaScript的接口类,主要用于创建对象、调用方法等功能。大部分功能在头文件v8.h
(在node文件夹下的路径为deps/v8/include/v8.h
)中有详细文档。
libuv 基于C的事件循环库,当需要等待的文件描述符可读时,等待定时器,或者等到接受信号时,会调用libuv的接口,也可以说,任何I/O操作,都需要调用libuv库
内部Node的库,可以通过node::ObjectWrap
来调用Node.js内部的库。
其他的一些类库同样可以在deps/ 中找到。
Node已将所有依赖关系静态地编译成可执行文件,因此我们在编译自己的组件时不需要担心和这些类库的链接问题。
让我们着手编写一个Addon的小例子,来达到如下模块同样的效果:
module.exports.hello = function() { return 'world'; };
首先,我们需要新建一个hello.cc文件
#include <node.h>
#include <v8.h>
using namespace v8; Handle<Value> Method(const Arguments& args) {
HandleScope scope;
return scope.Close(String::New("world"));
}
void init(Handle<Object> exports) {
exports->Set(String::NewSymbol("hello"),
FunctionTemplate::New(Method)->GetFunction());
}
NODE_MODULE(hello, init)
请注意:所有的Node Addons 必须通过以下初始化代码导出
void Initialize (Handle<Object> exports);
NODE_MODULE(module_name, Initialize)
NODE_MODULE 结尾没有带上分号,因为它不是一个函数(详细可以看node.h
)
module_name 是最终生成的二进制模块文件名称
代码将会被编译成hello.node,Addon的二进制文件,在这之前,需要创建一个叫binding.gyp的json格式文件来配置node-gyp进行编译。
{
"targets": [ { "target_name": "hello", "sources": [ "hello.cc" ] } ] }
执行node-gyp configure
生成合适的当前平台的工程建设文件。不需要传统的Makefile
或vcxproj
。
执行node-gyp build
编译项目,生成.node
文件,编译生成的目录在 build/Release/
编译成功后,可以在node.js项目中进行调用,创建hello.js
文件通过require函数调用刚编译完的hello.node模块。
var addon = require('./build/Release/hello');
console.log(addon.hello()); // 'world'
原文:http://blog.whattoc.com/2013/09/07/nodejs_api_addon_1/