diff options
Diffstat (limited to 'doc/api/addons.markdown')
-rw-r--r-- | doc/api/addons.markdown | 87 |
1 files changed, 49 insertions, 38 deletions
diff --git a/doc/api/addons.markdown b/doc/api/addons.markdown index b414943c6..3f5650ff3 100644 --- a/doc/api/addons.markdown +++ b/doc/api/addons.markdown @@ -6,30 +6,35 @@ knowledge of several libraries: - V8 JavaScript, a C++ library. Used for interfacing with JavaScript: creating objects, calling functions, etc. Documented mostly in the - `v8.h` header file (`deps/v8/include/v8.h` in the Node source tree), - which is also available [online](http://izs.me/v8-docs/main.html). + `v8.h` header file (`deps/v8/include/v8.h` in the Node source + tree), which is also available + [online](http://izs.me/v8-docs/main.html). - - [libuv](https://github.com/joyent/libuv), C event loop library. Anytime one - needs to wait for a file descriptor to become readable, wait for a timer, or - wait for a signal to received one will need to interface with libuv. That is, - if you perform any I/O, libuv will need to be used. + - [libuv](https://github.com/joyent/libuv), C event loop library. + Anytime one needs to wait for a file descriptor to become readable, + wait for a timer, or wait for a signal to received one will need to + interface with libuv. That is, if you perform any I/O, libuv will + need to be used. - Internal Node libraries. Most importantly is the `node::ObjectWrap` class which you will likely want to derive from. - Others. Look in `deps/` for what else is available. -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. +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 +48,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 +160,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 +195,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 +236,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 +247,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 +277,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 +289,7 @@ To test: var addon = require('./build/Release/addon'); - var fn = addon.createFunction(); + var fn = addon(); console.log(fn()); // 'hello world' @@ -294,8 +305,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 +320,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 +346,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 +356,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 +410,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 +501,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 +544,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()); } |