Browse Source

doc: NODE_MODULE() to pass full `module` to addons

mainly to allow native addons to export single functions on `exports`
rather than being restricted to operating on an existing `exports`
object.

added link to addons repo in docs
v0.9.9-release
Rod Vagg 12 years ago
committed by isaacs
parent
commit
f210710795
  1. 66
      doc/api/addons.markdown

66
doc/api/addons.markdown

@ -23,13 +23,15 @@ Node statically compiles all its dependencies into the executable. When
compiling your module, you don't need to worry about linking to any of these
libraries.
All of the following examples are available for [download](https://github.com/rvagg/node-addon-examples)
and may be used as a starting-point for your own Addon.
## Hello world
To get started let's make a small Addon which is the C++ equivalent of
the following JavaScript code:
exports.hello = function() { return 'world'; };
module.exports.hello = function() { return 'world'; };
First we create a file `hello.cc`:
@ -43,15 +45,16 @@ First we create a file `hello.cc`:
return scope.Close(String::New("world"));
}
void init(Handle<Object> target) {
target->Set(String::NewSymbol("hello"),
void init(Handle<Object> exports) {
exports->Set(String::NewSymbol("hello"),
FunctionTemplate::New(Method)->GetFunction());
}
NODE_MODULE(hello, init)
Note that all Node addons must export an initialization function:
void Initialize (Handle<Object> target);
void Initialize (Handle<Object> exports);
NODE_MODULE(module_name, Initialize)
There is no semi-colon after `NODE_MODULE` as it's not a function (see `node.h`).
@ -154,8 +157,8 @@ function calls and return a result. This is the main and only needed source
return scope.Close(num);
}
void Init(Handle<Object> target) {
target->Set(String::NewSymbol("add"),
void Init(Handle<Object> exports) {
exports->Set(String::NewSymbol("add"),
FunctionTemplate::New(Add)->GetFunction());
}
@ -189,18 +192,23 @@ there. Here's `addon.cc`:
return scope.Close(Undefined());
}
void Init(Handle<Object> target) {
target->Set(String::NewSymbol("runCallback"),
void Init(Handle<Object> exports, Handle<Object> module) {
module->Set(String::NewSymbol("exports"),
FunctionTemplate::New(RunCallback)->GetFunction());
}
NODE_MODULE(addon, Init)
Note that this example uses a two-argument form of `Init()` that receives
the full `module` object as the second argument. This allows the addon
to completely overwrite `exports` with a single function instead of
adding the function as a property of `exports`.
To test it run the following JavaScript snippet:
var addon = require('./build/Release/addon');
addon.runCallback(function(msg){
addon(function(msg){
console.log(msg); // 'hello world'
});
@ -225,8 +233,8 @@ the string passed to `createObject()`:
return scope.Close(obj);
}
void Init(Handle<Object> target) {
target->Set(String::NewSymbol("createObject"),
void Init(Handle<Object> exports, Handle<Object> module) {
module->Set(String::NewSymbol("exports"),
FunctionTemplate::New(CreateObject)->GetFunction());
}
@ -236,8 +244,8 @@ To test it in JavaScript:
var addon = require('./build/Release/addon');
var obj1 = addon.createObject('hello');
var obj2 = addon.createObject('world');
var obj1 = addon('hello');
var obj2 = addon('world');
console.log(obj1.msg+' '+obj2.msg); // 'hello world'
@ -266,8 +274,8 @@ wraps a C++ function:
return scope.Close(fn);
}
void Init(Handle<Object> target) {
target->Set(String::NewSymbol("createFunction"),
void Init(Handle<Object> exports, Handle<Object> module) {
module->Set(String::NewSymbol("exports"),
FunctionTemplate::New(CreateFunction)->GetFunction());
}
@ -278,7 +286,7 @@ To test:
var addon = require('./build/Release/addon');
var fn = addon.createFunction();
var fn = addon();
console.log(fn()); // 'hello world'
@ -294,8 +302,8 @@ module `addon.cc`:
using namespace v8;
void InitAll(Handle<Object> target) {
MyObject::Init(target);
void InitAll(Handle<Object> exports) {
MyObject::Init(exports);
}
NODE_MODULE(addon, InitAll)
@ -309,7 +317,7 @@ Then in `myobject.h` make your wrapper inherit from `node::ObjectWrap`:
class MyObject : public node::ObjectWrap {
public:
static void Init(v8::Handle<v8::Object> target);
static void Init(v8::Handle<v8::Object> exports);
private:
MyObject();
@ -335,7 +343,7 @@ prototype:
MyObject::MyObject() {};
MyObject::~MyObject() {};
void MyObject::Init(Handle<Object> target) {
void MyObject::Init(Handle<Object> exports) {
// Prepare constructor template
Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
tpl->SetClassName(String::NewSymbol("MyObject"));
@ -345,7 +353,7 @@ prototype:
FunctionTemplate::New(PlusOne)->GetFunction());
Persistent<Function> constructor = Persistent<Function>::New(tpl->GetFunction());
target->Set(String::NewSymbol("MyObject"), constructor);
exports->Set(String::NewSymbol("MyObject"), constructor);
}
Handle<Value> MyObject::New(const Arguments& args) {
@ -399,10 +407,10 @@ Let's register our `createObject` method in `addon.cc`:
return scope.Close(MyObject::NewInstance(args));
}
void InitAll(Handle<Object> target) {
void InitAll(Handle<Object> exports, Handle<Object> module) {
MyObject::Init();
target->Set(String::NewSymbol("createObject"),
module->Set(String::NewSymbol("exports"),
FunctionTemplate::New(CreateObject)->GetFunction());
}
@ -490,14 +498,14 @@ The implementation is similar to the above in `myobject.cc`:
Test it with:
var addon = require('./build/Release/addon');
var createObject = require('./build/Release/addon');
var obj = addon.createObject(10);
var obj = createObject(10);
console.log( obj.plusOne() ); // 11
console.log( obj.plusOne() ); // 12
console.log( obj.plusOne() ); // 13
var obj2 = addon.createObject(20);
var obj2 = createObject(20);
console.log( obj2.plusOne() ); // 21
console.log( obj2.plusOne() ); // 22
console.log( obj2.plusOne() ); // 23
@ -533,13 +541,13 @@ In the following `addon.cc` we introduce a function `add()` that can take on two
return scope.Close(Number::New(sum));
}
void InitAll(Handle<Object> target) {
void InitAll(Handle<Object> exports) {
MyObject::Init();
target->Set(String::NewSymbol("createObject"),
exports->Set(String::NewSymbol("createObject"),
FunctionTemplate::New(CreateObject)->GetFunction());
target->Set(String::NewSymbol("add"),
exports->Set(String::NewSymbol("add"),
FunctionTemplate::New(Add)->GetFunction());
}

Loading…
Cancel
Save