{
  "source": "doc/api/addons.markdown",
  "modules": [
    {
      "textRaw": "Addons",
      "name": "addons",
      "desc": "<p>Addons are dynamically-linked shared objects. They can provide glue to C and\nC++ libraries. The API (at the moment) is rather complex, involving\nknowledge of several libraries:\n\n</p>\n<ul>\n<li><p>V8 JavaScript, a C++ library. Used for interfacing with JavaScript:\ncreating objects, calling functions, etc.  Documented mostly in the\n<code>v8.h</code> header file (<code>deps/v8/include/v8.h</code> in the Node.js source\ntree), which is also available [online][].</p>\n</li>\n<li><p>[libuv][], C event loop library. Anytime one needs to wait for a file\ndescriptor to become readable, wait for a timer, or wait for a signal\nto be received, one will need to interface with libuv. That is, if you\nperform any I/O, libuv will need to be used.</p>\n</li>\n<li><p>Internal Node.js libraries. The most important class is <code>node::ObjectWrap</code>\nwhich you will likely want to derive from.</p>\n</li>\n<li><p>Others. Look in <code>deps/</code> for what else is available.</p>\n</li>\n</ul>\n<p>Node.js statically compiles all its dependencies into the executable.\nWhen compiling your module, you don&#39;t need to worry about linking to\nany of these libraries.\n\n</p>\n<p>All of the following examples are available for [download][] and may\nbe used as a starting-point for your own Addon.\n\n</p>\n",
      "modules": [
        {
          "textRaw": "Hello world",
          "name": "hello_world",
          "desc": "<p>To get started, let&#39;s make a small Addon which is the C++ equivalent of\nthe following JavaScript code:\n\n</p>\n<pre><code>module.exports.hello = function() { return &#39;world&#39;; };</code></pre>\n<p>First we create a file <code>hello.cc</code>:\n\n</p>\n<pre><code>// hello.cc\n#include &lt;node.h&gt;\n\nnamespace demo {\n\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid Method(const FunctionCallbackInfo&lt;Value&gt;&amp; args) {\n  Isolate* isolate = args.GetIsolate();\n  args.GetReturnValue().Set(String::NewFromUtf8(isolate, &quot;world&quot;));\n}\n\nvoid init(Local&lt;Object&gt; exports) {\n  NODE_SET_METHOD(exports, &quot;hello&quot;, Method);\n}\n\nNODE_MODULE(addon, init)\n\n}  // namespace demo</code></pre>\n<p>Note that all Node.js addons must export an initialization function:\n\n</p>\n<pre><code>void Initialize(Local&lt;Object&gt; exports);\nNODE_MODULE(module_name, Initialize)</code></pre>\n<p>There is no semi-colon after <code>NODE_MODULE</code> as it&#39;s not a function (see\n<code>node.h</code>).\n\n</p>\n<p>The <code>module_name</code> needs to match the filename of the final binary (excluding\nthe .node suffix).\n\n</p>\n<p>The source code needs to be built into <code>addon.node</code>, the binary Addon. To\ndo this, we create a file called <code>binding.gyp</code> which describes the configuration\nto build your module in a JSON-like format. This file gets compiled by\n[node-gyp][].\n\n</p>\n<pre><code>{\n  &quot;targets&quot;: [\n    {\n      &quot;target_name&quot;: &quot;addon&quot;,\n      &quot;sources&quot;: [ &quot;hello.cc&quot; ]\n    }\n  ]\n}</code></pre>\n<p>The next step is to generate the appropriate project build files for the\ncurrent platform. Use <code>node-gyp configure</code> for that.\n\n</p>\n<p>Now you will have either a <code>Makefile</code> (on Unix platforms) or a <code>vcxproj</code> file\n(on Windows) in the <code>build/</code> directory. Next, invoke the <code>node-gyp build</code>\ncommand.\n\n</p>\n<p>Now you have your compiled <code>.node</code> bindings file! The compiled bindings end up\nin <code>build/Release/</code>.\n\n</p>\n<p>You can now use the binary addon in a Node.js project <code>hello.js</code> by pointing\n<code>require</code> to the recently built <code>hello.node</code> module:\n\n</p>\n<pre><code>// hello.js\nconst addon = require(&#39;./build/Release/addon&#39;);\n\nconsole.log(addon.hello()); // &#39;world&#39;</code></pre>\n<p>Please see patterns below for further information or\n</p>\n<p><a href=\"https://github.com/arturadib/node-qt\">https://github.com/arturadib/node-qt</a> for an example in production.\n\n\n</p>\n",
          "type": "module",
          "displayName": "Hello world"
        },
        {
          "textRaw": "Addon patterns",
          "name": "addon_patterns",
          "desc": "<p>Below are some addon patterns to help you get started. Consult the online\n[v8 reference][] for help with the various v8 calls, and v8&#39;s\n[Embedder&#39;s Guide][] for an explanation of several concepts used such as\nhandles, scopes, function templates, etc.\n\n</p>\n<p>In order to use these examples, you need to compile them using <code>node-gyp</code>.\nCreate the following <code>binding.gyp</code> file:\n\n</p>\n<pre><code>{\n  &quot;targets&quot;: [\n    {\n      &quot;target_name&quot;: &quot;addon&quot;,\n      &quot;sources&quot;: [ &quot;addon.cc&quot; ]\n    }\n  ]\n}</code></pre>\n<p>In cases where there is more than one <code>.cc</code> file, simply add the file name to\nthe <code>sources</code> array. For example:\n\n</p>\n<pre><code>&quot;sources&quot;: [&quot;addon.cc&quot;, &quot;myexample.cc&quot;]</code></pre>\n<p>Now that you have your <code>binding.gyp</code> ready, you can configure and build the\naddon:\n\n</p>\n<pre><code>$ node-gyp configure build</code></pre>\n",
          "modules": [
            {
              "textRaw": "Function arguments",
              "name": "function_arguments",
              "desc": "<p>The following pattern illustrates how to read arguments from JavaScript\nfunction calls and return a result. This is the main and only needed source\n<code>addon.cc</code>:\n\n</p>\n<pre><code>// addon.cc\n#include &lt;node.h&gt;\n\nnamespace demo {\n\nusing v8::Exception;\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Number;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid Add(const FunctionCallbackInfo&lt;Value&gt;&amp; args) {\n  Isolate* isolate = args.GetIsolate();\n\n  if (args.Length() &lt; 2) {\n    isolate-&gt;ThrowException(Exception::TypeError(\n        String::NewFromUtf8(isolate, &quot;Wrong number of arguments&quot;)));\n    return;\n  }\n\n  if (!args[0]-&gt;IsNumber() || !args[1]-&gt;IsNumber()) {\n    isolate-&gt;ThrowException(Exception::TypeError(\n        String::NewFromUtf8(isolate, &quot;Wrong arguments&quot;)));\n    return;\n  }\n\n  double value = args[0]-&gt;NumberValue() + args[1]-&gt;NumberValue();\n  Local&lt;Number&gt; num = Number::New(isolate, value);\n\n  args.GetReturnValue().Set(num);\n}\n\nvoid Init(Local&lt;Object&gt; exports) {\n  NODE_SET_METHOD(exports, &quot;add&quot;, Add);\n}\n\nNODE_MODULE(addon, Init)\n\n}  // namespace demo</code></pre>\n<p>You can test it with the following JavaScript snippet:\n\n</p>\n<pre><code>// test.js\nconst addon = require(&#39;./build/Release/addon&#39;);\n\nconsole.log( &#39;This should be eight:&#39;, addon.add(3,5) );</code></pre>\n",
              "type": "module",
              "displayName": "Function arguments"
            },
            {
              "textRaw": "Callbacks",
              "name": "callbacks",
              "desc": "<p>You can pass JavaScript functions to a C++ function and execute them from\nthere. Here&#39;s <code>addon.cc</code>:\n\n</p>\n<pre><code>// addon.cc\n#include &lt;node.h&gt;\n\nnamespace demo {\n\nusing v8::Function;\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Null;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid RunCallback(const FunctionCallbackInfo&lt;Value&gt;&amp; args) {\n  Isolate* isolate = args.GetIsolate();\n  Local&lt;Function&gt; cb = Local&lt;Function&gt;::Cast(args[0]);\n  const unsigned argc = 1;\n  Local&lt;Value&gt; argv[argc] = { String::NewFromUtf8(isolate, &quot;hello world&quot;) };\n  cb-&gt;Call(Null(isolate), argc, argv);\n}\n\nvoid Init(Local&lt;Object&gt; exports, Local&lt;Object&gt; module) {\n  NODE_SET_METHOD(module, &quot;exports&quot;, RunCallback);\n}\n\nNODE_MODULE(addon, Init)\n\n}  // namespace demo</code></pre>\n<p>Note that this example uses a two-argument form of <code>Init()</code> that receives\nthe full <code>module</code> object as the second argument. This allows the addon\nto completely overwrite <code>exports</code> with a single function instead of\nadding the function as a property of <code>exports</code>.\n\n</p>\n<p>To test it, run the following JavaScript snippet:\n\n</p>\n<pre><code>// test.js\nconst addon = require(&#39;./build/Release/addon&#39;);\n\naddon(function(msg){\n  console.log(msg); // &#39;hello world&#39;\n});</code></pre>\n",
              "type": "module",
              "displayName": "Callbacks"
            },
            {
              "textRaw": "Object factory",
              "name": "object_factory",
              "desc": "<p>You can create and return new objects from within a C++ function with this\n<code>addon.cc</code> pattern, which returns an object with property <code>msg</code> that echoes\nthe string passed to <code>createObject()</code>:\n\n</p>\n<pre><code>// addon.cc\n#include &lt;node.h&gt;\n\nnamespace demo {\n\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid CreateObject(const FunctionCallbackInfo&lt;Value&gt;&amp; args) {\n  Isolate* isolate = args.GetIsolate();\n\n  Local&lt;Object&gt; obj = Object::New(isolate);\n  obj-&gt;Set(String::NewFromUtf8(isolate, &quot;msg&quot;), args[0]-&gt;ToString());\n\n  args.GetReturnValue().Set(obj);\n}\n\nvoid Init(Local&lt;Object&gt; exports, Local&lt;Object&gt; module) {\n  NODE_SET_METHOD(module, &quot;exports&quot;, CreateObject);\n}\n\nNODE_MODULE(addon, Init)\n\n}  // namespace demo</code></pre>\n<p>To test it in JavaScript:\n\n</p>\n<pre><code>// test.js\nconst addon = require(&#39;./build/Release/addon&#39;);\n\nvar obj1 = addon(&#39;hello&#39;);\nvar obj2 = addon(&#39;world&#39;);\nconsole.log(obj1.msg+&#39; &#39;+obj2.msg); // &#39;hello world&#39;</code></pre>\n",
              "type": "module",
              "displayName": "Object factory"
            },
            {
              "textRaw": "Function factory",
              "name": "function_factory",
              "desc": "<p>This pattern illustrates how to create and return a JavaScript function that\nwraps a C++ function:\n\n</p>\n<pre><code>// addon.cc\n#include &lt;node.h&gt;\n\nnamespace demo {\n\nusing v8::Function;\nusing v8::FunctionCallbackInfo;\nusing v8::FunctionTemplate;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid MyFunction(const FunctionCallbackInfo&lt;Value&gt;&amp; args) {\n  Isolate* isolate = args.GetIsolate();\n  args.GetReturnValue().Set(String::NewFromUtf8(isolate, &quot;hello world&quot;));\n}\n\nvoid CreateFunction(const FunctionCallbackInfo&lt;Value&gt;&amp; args) {\n  Isolate* isolate = args.GetIsolate();\n\n  Local&lt;FunctionTemplate&gt; tpl = FunctionTemplate::New(isolate, MyFunction);\n  Local&lt;Function&gt; fn = tpl-&gt;GetFunction();\n\n  // omit this to make it anonymous\n  fn-&gt;SetName(String::NewFromUtf8(isolate, &quot;theFunction&quot;));\n\n  args.GetReturnValue().Set(fn);\n}\n\nvoid Init(Local&lt;Object&gt; exports, Local&lt;Object&gt; module) {\n  NODE_SET_METHOD(module, &quot;exports&quot;, CreateFunction);\n}\n\nNODE_MODULE(addon, Init)\n\n}  // namespace demo</code></pre>\n<p>To test:\n\n</p>\n<pre><code>// test.js\nconst addon = require(&#39;./build/Release/addon&#39;);\n\nvar fn = addon();\nconsole.log(fn()); // &#39;hello world&#39;</code></pre>\n",
              "type": "module",
              "displayName": "Function factory"
            },
            {
              "textRaw": "Wrapping C++ objects",
              "name": "wrapping_c++_objects",
              "desc": "<p>Here, we will create a wrapper for a C++ object/class <code>MyObject</code> that can be\ninstantiated in JavaScript through the <code>new</code> operator. First, prepare the main\nmodule <code>addon.cc</code>:\n\n</p>\n<pre><code>// addon.cc\n#include &lt;node.h&gt;\n#include &quot;myobject.h&quot;\n\nnamespace demo {\n\nusing v8::Local;\nusing v8::Object;\n\nvoid InitAll(Local&lt;Object&gt; exports) {\n  MyObject::Init(exports);\n}\n\nNODE_MODULE(addon, InitAll)\n\n}  // namespace demo</code></pre>\n<p>Then, in <code>myobject.h</code>, make your wrapper inherit from <code>node::ObjectWrap</code>:\n\n</p>\n<pre><code>// myobject.h\n#ifndef MYOBJECT_H\n#define MYOBJECT_H\n\n#include &lt;node.h&gt;\n#include &lt;node_object_wrap.h&gt;\n\nnamespace demo {\n\nclass MyObject : public node::ObjectWrap {\n public:\n  static void Init(v8::Local&lt;v8::Object&gt; exports);\n\n private:\n  explicit MyObject(double value = 0);\n  ~MyObject();\n\n  static void New(const v8::FunctionCallbackInfo&lt;v8::Value&gt;&amp; args);\n  static void PlusOne(const v8::FunctionCallbackInfo&lt;v8::Value&gt;&amp; args);\n  static v8::Persistent&lt;v8::Function&gt; constructor;\n  double value_;\n};\n\n}  // namespace demo\n\n#endif</code></pre>\n<p>And in <code>myobject.cc</code>, implement the various methods that you want to expose.\nHere we expose the method <code>plusOne</code> by adding it to the constructor&#39;s\nprototype:\n\n</p>\n<pre><code>// myobject.cc\n#include &quot;myobject.h&quot;\n\nnamespace demo {\n\nusing v8::Function;\nusing v8::FunctionCallbackInfo;\nusing v8::FunctionTemplate;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Number;\nusing v8::Object;\nusing v8::Persistent;\nusing v8::String;\nusing v8::Value;\n\nPersistent&lt;Function&gt; MyObject::constructor;\n\nMyObject::MyObject(double value) : value_(value) {\n}\n\nMyObject::~MyObject() {\n}\n\nvoid MyObject::Init(Local&lt;Object&gt; exports) {\n  Isolate* isolate = exports-&gt;GetIsolate();\n\n  // Prepare constructor template\n  Local&lt;FunctionTemplate&gt; tpl = FunctionTemplate::New(isolate, New);\n  tpl-&gt;SetClassName(String::NewFromUtf8(isolate, &quot;MyObject&quot;));\n  tpl-&gt;InstanceTemplate()-&gt;SetInternalFieldCount(1);\n\n  // Prototype\n  NODE_SET_PROTOTYPE_METHOD(tpl, &quot;plusOne&quot;, PlusOne);\n\n  constructor.Reset(isolate, tpl-&gt;GetFunction());\n  exports-&gt;Set(String::NewFromUtf8(isolate, &quot;MyObject&quot;),\n               tpl-&gt;GetFunction());\n}\n\nvoid MyObject::New(const FunctionCallbackInfo&lt;Value&gt;&amp; args) {\n  Isolate* isolate = args.GetIsolate();\n\n  if (args.IsConstructCall()) {\n    // Invoked as constructor: `new MyObject(...)`\n    double value = args[0]-&gt;IsUndefined() ? 0 : args[0]-&gt;NumberValue();\n    MyObject* obj = new MyObject(value);\n    obj-&gt;Wrap(args.This());\n    args.GetReturnValue().Set(args.This());\n  } else {\n    // Invoked as plain function `MyObject(...)`, turn into construct call.\n    const int argc = 1;\n    Local&lt;Value&gt; argv[argc] = { args[0] };\n    Local&lt;Function&gt; cons = Local&lt;Function&gt;::New(isolate, constructor);\n    args.GetReturnValue().Set(cons-&gt;NewInstance(argc, argv));\n  }\n}\n\nvoid MyObject::PlusOne(const FunctionCallbackInfo&lt;Value&gt;&amp; args) {\n  Isolate* isolate = args.GetIsolate();\n\n  MyObject* obj = ObjectWrap::Unwrap&lt;MyObject&gt;(args.Holder());\n  obj-&gt;value_ += 1;\n\n  args.GetReturnValue().Set(Number::New(isolate, obj-&gt;value_));\n}\n\n}  // namespace demo</code></pre>\n<p>Test it with:\n\n</p>\n<pre><code>// test.js\nconst addon = require(&#39;./build/Release/addon&#39;);\n\nvar obj = new addon.MyObject(10);\nconsole.log( obj.plusOne() ); // 11\nconsole.log( obj.plusOne() ); // 12\nconsole.log( obj.plusOne() ); // 13</code></pre>\n",
              "type": "module",
              "displayName": "Wrapping C++ objects"
            },
            {
              "textRaw": "Factory of wrapped objects",
              "name": "factory_of_wrapped_objects",
              "desc": "<p>This is useful when you want to be able to create native objects without\nexplicitly instantiating them with the <code>new</code> operator in JavaScript. For\nexample:\n\n</p>\n<pre><code>var obj = addon.createObject();\n// instead of:\n// var obj = new addon.Object();</code></pre>\n<p>Let&#39;s register our <code>createObject</code> method in <code>addon.cc</code>:\n\n</p>\n<pre><code>// addon.cc\n#include &lt;node.h&gt;\n#include &quot;myobject.h&quot;\n\nnamespace demo {\n\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid CreateObject(const FunctionCallbackInfo&lt;Value&gt;&amp; args) {\n  MyObject::NewInstance(args);\n}\n\nvoid InitAll(Local&lt;Object&gt; exports, Local&lt;Object&gt; module) {\n  MyObject::Init(exports-&gt;GetIsolate());\n\n  NODE_SET_METHOD(module, &quot;exports&quot;, CreateObject);\n}\n\nNODE_MODULE(addon, InitAll)\n\n}  // namespace demo</code></pre>\n<p>In <code>myobject.h</code>, we now introduce the static method <code>NewInstance</code> that takes\ncare of instantiating the object. In other words, it does the job of <code>new</code> in\nJavaScript:\n\n</p>\n<pre><code>// myobject.h\n#ifndef MYOBJECT_H\n#define MYOBJECT_H\n\n#include &lt;node.h&gt;\n#include &lt;node_object_wrap.h&gt;\n\nnamespace demo {\n\nclass MyObject : public node::ObjectWrap {\n public:\n  static void Init(v8::Isolate* isolate);\n  static void NewInstance(const v8::FunctionCallbackInfo&lt;v8::Value&gt;&amp; args);\n\n private:\n  explicit MyObject(double value = 0);\n  ~MyObject();\n\n  static void New(const v8::FunctionCallbackInfo&lt;v8::Value&gt;&amp; args);\n  static void PlusOne(const v8::FunctionCallbackInfo&lt;v8::Value&gt;&amp; args);\n  static v8::Persistent&lt;v8::Function&gt; constructor;\n  double value_;\n};\n\n}  // namespace demo\n\n#endif</code></pre>\n<p>The implementation is similar to the above in <code>myobject.cc</code>:\n\n</p>\n<pre><code>// myobject.cc\n#include &lt;node.h&gt;\n#include &quot;myobject.h&quot;\n\nnamespace demo {\n\nusing v8::Function;\nusing v8::FunctionCallbackInfo;\nusing v8::FunctionTemplate;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Number;\nusing v8::Object;\nusing v8::Persistent;\nusing v8::String;\nusing v8::Value;\n\nPersistent&lt;Function&gt; MyObject::constructor;\n\nMyObject::MyObject(double value) : value_(value) {\n}\n\nMyObject::~MyObject() {\n}\n\nvoid MyObject::Init(Isolate* isolate) {\n  // Prepare constructor template\n  Local&lt;FunctionTemplate&gt; tpl = FunctionTemplate::New(isolate, New);\n  tpl-&gt;SetClassName(String::NewFromUtf8(isolate, &quot;MyObject&quot;));\n  tpl-&gt;InstanceTemplate()-&gt;SetInternalFieldCount(1);\n\n  // Prototype\n  NODE_SET_PROTOTYPE_METHOD(tpl, &quot;plusOne&quot;, PlusOne);\n\n  constructor.Reset(isolate, tpl-&gt;GetFunction());\n}\n\nvoid MyObject::New(const FunctionCallbackInfo&lt;Value&gt;&amp; args) {\n  Isolate* isolate = args.GetIsolate();\n\n  if (args.IsConstructCall()) {\n    // Invoked as constructor: `new MyObject(...)`\n    double value = args[0]-&gt;IsUndefined() ? 0 : args[0]-&gt;NumberValue();\n    MyObject* obj = new MyObject(value);\n    obj-&gt;Wrap(args.This());\n    args.GetReturnValue().Set(args.This());\n  } else {\n    // Invoked as plain function `MyObject(...)`, turn into construct call.\n    const int argc = 1;\n    Local&lt;Value&gt; argv[argc] = { args[0] };\n    Local&lt;Function&gt; cons = Local&lt;Function&gt;::New(isolate, constructor);\n    args.GetReturnValue().Set(cons-&gt;NewInstance(argc, argv));\n  }\n}\n\nvoid MyObject::NewInstance(const FunctionCallbackInfo&lt;Value&gt;&amp; args) {\n  Isolate* isolate = args.GetIsolate();\n\n  const unsigned argc = 1;\n  Local&lt;Value&gt; argv[argc] = { args[0] };\n  Local&lt;Function&gt; cons = Local&lt;Function&gt;::New(isolate, constructor);\n  Local&lt;Object&gt; instance = cons-&gt;NewInstance(argc, argv);\n\n  args.GetReturnValue().Set(instance);\n}\n\nvoid MyObject::PlusOne(const FunctionCallbackInfo&lt;Value&gt;&amp; args) {\n  Isolate* isolate = args.GetIsolate();\n\n  MyObject* obj = ObjectWrap::Unwrap&lt;MyObject&gt;(args.Holder());\n  obj-&gt;value_ += 1;\n\n  args.GetReturnValue().Set(Number::New(isolate, obj-&gt;value_));\n}\n\n}  // namespace demo</code></pre>\n<p>Test it with:\n\n</p>\n<pre><code>// test.js\nconst createObject = require(&#39;./build/Release/addon&#39;);\n\nvar obj = createObject(10);\nconsole.log( obj.plusOne() ); // 11\nconsole.log( obj.plusOne() ); // 12\nconsole.log( obj.plusOne() ); // 13\n\nvar obj2 = createObject(20);\nconsole.log( obj2.plusOne() ); // 21\nconsole.log( obj2.plusOne() ); // 22\nconsole.log( obj2.plusOne() ); // 23</code></pre>\n",
              "type": "module",
              "displayName": "Factory of wrapped objects"
            },
            {
              "textRaw": "Passing wrapped objects around",
              "name": "passing_wrapped_objects_around",
              "desc": "<p>In addition to wrapping and returning C++ objects, you can pass them around\nby unwrapping them with the Node.js helper function <code>node::ObjectWrap::Unwrap</code>.\nIn the following <code>addon.cc</code>, we introduce a function <code>add()</code> that can take on\ntwo <code>MyObject</code> objects:\n\n</p>\n<pre><code>// addon.cc\n#include &lt;node.h&gt;\n#include &lt;node_object_wrap.h&gt;\n#include &quot;myobject.h&quot;\n\nnamespace demo {\n\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Number;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid CreateObject(const FunctionCallbackInfo&lt;Value&gt;&amp; args) {\n  MyObject::NewInstance(args);\n}\n\nvoid Add(const FunctionCallbackInfo&lt;Value&gt;&amp; args) {\n  Isolate* isolate = args.GetIsolate();\n\n  MyObject* obj1 = node::ObjectWrap::Unwrap&lt;MyObject&gt;(\n      args[0]-&gt;ToObject());\n  MyObject* obj2 = node::ObjectWrap::Unwrap&lt;MyObject&gt;(\n      args[1]-&gt;ToObject());\n\n  double sum = obj1-&gt;value() + obj2-&gt;value();\n  args.GetReturnValue().Set(Number::New(isolate, sum));\n}\n\nvoid InitAll(Local&lt;Object&gt; exports) {\n  MyObject::Init(exports-&gt;GetIsolate());\n\n  NODE_SET_METHOD(exports, &quot;createObject&quot;, CreateObject);\n  NODE_SET_METHOD(exports, &quot;add&quot;, Add);\n}\n\nNODE_MODULE(addon, InitAll)\n\n}  // namespace demo</code></pre>\n<p>To make things interesting, we introduce a public method in <code>myobject.h</code> so we\ncan probe private values after unwrapping the object:\n\n</p>\n<pre><code>// myobject.h\n#ifndef MYOBJECT_H\n#define MYOBJECT_H\n\n#include &lt;node.h&gt;\n#include &lt;node_object_wrap.h&gt;\n\nnamespace demo {\n\nclass MyObject : public node::ObjectWrap {\n public:\n  static void Init(v8::Isolate* isolate);\n  static void NewInstance(const v8::FunctionCallbackInfo&lt;v8::Value&gt;&amp; args);\n  inline double value() const { return value_; }\n\n private:\n  explicit MyObject(double value = 0);\n  ~MyObject();\n\n  static void New(const v8::FunctionCallbackInfo&lt;v8::Value&gt;&amp; args);\n  static v8::Persistent&lt;v8::Function&gt; constructor;\n  double value_;\n};\n\n}  // namespace demo\n\n#endif</code></pre>\n<p>The implementation of <code>myobject.cc</code> is similar to before:\n\n</p>\n<pre><code>// myobject.cc\n#include &lt;node.h&gt;\n#include &quot;myobject.h&quot;\n\nnamespace demo {\n\nusing v8::Function;\nusing v8::FunctionCallbackInfo;\nusing v8::FunctionTemplate;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Object;\nusing v8::Persistent;\nusing v8::String;\nusing v8::Value;\n\nPersistent&lt;Function&gt; MyObject::constructor;\n\nMyObject::MyObject(double value) : value_(value) {\n}\n\nMyObject::~MyObject() {\n}\n\nvoid MyObject::Init(Isolate* isolate) {\n  // Prepare constructor template\n  Local&lt;FunctionTemplate&gt; tpl = FunctionTemplate::New(isolate, New);\n  tpl-&gt;SetClassName(String::NewFromUtf8(isolate, &quot;MyObject&quot;));\n  tpl-&gt;InstanceTemplate()-&gt;SetInternalFieldCount(1);\n\n  constructor.Reset(isolate, tpl-&gt;GetFunction());\n}\n\nvoid MyObject::New(const FunctionCallbackInfo&lt;Value&gt;&amp; args) {\n  Isolate* isolate = args.GetIsolate();\n\n  if (args.IsConstructCall()) {\n    // Invoked as constructor: `new MyObject(...)`\n    double value = args[0]-&gt;IsUndefined() ? 0 : args[0]-&gt;NumberValue();\n    MyObject* obj = new MyObject(value);\n    obj-&gt;Wrap(args.This());\n    args.GetReturnValue().Set(args.This());\n  } else {\n    // Invoked as plain function `MyObject(...)`, turn into construct call.\n    const int argc = 1;\n    Local&lt;Value&gt; argv[argc] = { args[0] };\n    Local&lt;Function&gt; cons = Local&lt;Function&gt;::New(isolate, constructor);\n    args.GetReturnValue().Set(cons-&gt;NewInstance(argc, argv));\n  }\n}\n\nvoid MyObject::NewInstance(const FunctionCallbackInfo&lt;Value&gt;&amp; args) {\n  Isolate* isolate = args.GetIsolate();\n\n  const unsigned argc = 1;\n  Local&lt;Value&gt; argv[argc] = { args[0] };\n  Local&lt;Function&gt; cons = Local&lt;Function&gt;::New(isolate, constructor);\n  Local&lt;Object&gt; instance = cons-&gt;NewInstance(argc, argv);\n\n  args.GetReturnValue().Set(instance);\n}\n\n}  // namespace demo</code></pre>\n<p>Test it with:\n\n</p>\n<pre><code>// test.js\nconst addon = require(&#39;./build/Release/addon&#39;);\n\nvar obj1 = addon.createObject(10);\nvar obj2 = addon.createObject(20);\nvar result = addon.add(obj1, obj2);\n\nconsole.log(result); // 30</code></pre>\n",
              "type": "module",
              "displayName": "Passing wrapped objects around"
            },
            {
              "textRaw": "AtExit hooks",
              "name": "atexit_hooks",
              "modules": [
                {
                  "textRaw": "void AtExit(callback, args)",
                  "name": "void_atexit(callback,_args)",
                  "desc": "<p>Registers exit hooks that run after the event loop has ended but before the VM\nis killed.\n\n</p>\n<p>Callbacks are run in last-in first-out order. AtExit takes two parameters:\na pointer to a callback function to run at exit, and a pointer to untyped\ncontext data to be passed to that callback.\n\n</p>\n<p>The file <code>addon.cc</code> implements AtExit below:\n\n</p>\n<pre><code>// addon.cc\n#undef NDEBUG\n#include &lt;assert.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;node.h&gt;\n\nnamespace demo {\n\nusing node::AtExit;\nusing v8::HandleScope;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Object;\n\nstatic char cookie[] = &quot;yum yum&quot;;\nstatic int at_exit_cb1_called = 0;\nstatic int at_exit_cb2_called = 0;\n\nstatic void at_exit_cb1(void* arg) {\n  Isolate* isolate = static_cast&lt;Isolate*&gt;(arg);\n  HandleScope scope(isolate);\n  Local&lt;Object&gt; obj = Object::New(isolate);\n  assert(!obj.IsEmpty()); // assert VM is still alive\n  assert(obj-&gt;IsObject());\n  at_exit_cb1_called++;\n}\n\nstatic void at_exit_cb2(void* arg) {\n  assert(arg == static_cast&lt;void*&gt;(cookie));\n  at_exit_cb2_called++;\n}\n\nstatic void sanity_check(void*) {\n  assert(at_exit_cb1_called == 1);\n  assert(at_exit_cb2_called == 2);\n}\n\nvoid init(Local&lt;Object&gt; exports) {\n  AtExit(sanity_check);\n  AtExit(at_exit_cb2, cookie);\n  AtExit(at_exit_cb2, cookie);\n  AtExit(at_exit_cb1, exports-&gt;GetIsolate());\n}\n\nNODE_MODULE(addon, init);\n\n}  // namespace demo</code></pre>\n<p>Test in JavaScript by running:\n\n</p>\n<pre><code>// test.js\nconst addon = require(&#39;./build/Release/addon&#39;);</code></pre>\n",
                  "type": "module",
                  "displayName": "void AtExit(callback, args)"
                }
              ],
              "type": "module",
              "displayName": "AtExit hooks"
            }
          ],
          "type": "module",
          "displayName": "Addon patterns"
        }
      ],
      "type": "module",
      "displayName": "Addons"
    }
  ]
}
