• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!DOCTYPE html>
2<html lang="en">
3<head>
4  <meta charset="utf-8">
5  <meta name="viewport" content="width=device-width">
6  <meta name="nodejs.org:node-version" content="v18.18.2">
7  <title>C++ addons | Node.js v18.18.2 Documentation</title>
8  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:400,700,400italic&display=fallback">
9  <link rel="stylesheet" href="assets/style.css">
10  <link rel="stylesheet" href="assets/hljs.css">
11  <link rel="canonical" href="https://nodejs.org/api/addons.html">
12  <script async defer src="assets/api.js" type="text/javascript"></script>
13
14</head>
15<body class="alt apidoc" id="api-section-addons">
16  <div id="content" class="clearfix">
17    <div id="column2" class="interior">
18      <div id="intro" class="interior">
19        <a href="/" title="Go back to the home page">
20          Node.js
21        </a>
22      </div>
23      <ul>
24<li><a href="documentation.html" class="nav-documentation">About this documentation</a></li>
25<li><a href="synopsis.html" class="nav-synopsis">Usage and example</a></li>
26</ul>
27<hr class="line">
28<ul>
29<li><a href="assert.html" class="nav-assert">Assertion testing</a></li>
30<li><a href="async_context.html" class="nav-async_context">Asynchronous context tracking</a></li>
31<li><a href="async_hooks.html" class="nav-async_hooks">Async hooks</a></li>
32<li><a href="buffer.html" class="nav-buffer">Buffer</a></li>
33<li><a href="addons.html" class="nav-addons active">C++ addons</a></li>
34<li><a href="n-api.html" class="nav-n-api">C/C++ addons with Node-API</a></li>
35<li><a href="embedding.html" class="nav-embedding">C++ embedder API</a></li>
36<li><a href="child_process.html" class="nav-child_process">Child processes</a></li>
37<li><a href="cluster.html" class="nav-cluster">Cluster</a></li>
38<li><a href="cli.html" class="nav-cli">Command-line options</a></li>
39<li><a href="console.html" class="nav-console">Console</a></li>
40<li><a href="corepack.html" class="nav-corepack">Corepack</a></li>
41<li><a href="crypto.html" class="nav-crypto">Crypto</a></li>
42<li><a href="debugger.html" class="nav-debugger">Debugger</a></li>
43<li><a href="deprecations.html" class="nav-deprecations">Deprecated APIs</a></li>
44<li><a href="diagnostics_channel.html" class="nav-diagnostics_channel">Diagnostics Channel</a></li>
45<li><a href="dns.html" class="nav-dns">DNS</a></li>
46<li><a href="domain.html" class="nav-domain">Domain</a></li>
47<li><a href="errors.html" class="nav-errors">Errors</a></li>
48<li><a href="events.html" class="nav-events">Events</a></li>
49<li><a href="fs.html" class="nav-fs">File system</a></li>
50<li><a href="globals.html" class="nav-globals">Globals</a></li>
51<li><a href="http.html" class="nav-http">HTTP</a></li>
52<li><a href="http2.html" class="nav-http2">HTTP/2</a></li>
53<li><a href="https.html" class="nav-https">HTTPS</a></li>
54<li><a href="inspector.html" class="nav-inspector">Inspector</a></li>
55<li><a href="intl.html" class="nav-intl">Internationalization</a></li>
56<li><a href="modules.html" class="nav-modules">Modules: CommonJS modules</a></li>
57<li><a href="esm.html" class="nav-esm">Modules: ECMAScript modules</a></li>
58<li><a href="module.html" class="nav-module">Modules: <code>node:module</code> API</a></li>
59<li><a href="packages.html" class="nav-packages">Modules: Packages</a></li>
60<li><a href="net.html" class="nav-net">Net</a></li>
61<li><a href="os.html" class="nav-os">OS</a></li>
62<li><a href="path.html" class="nav-path">Path</a></li>
63<li><a href="perf_hooks.html" class="nav-perf_hooks">Performance hooks</a></li>
64<li><a href="permissions.html" class="nav-permissions">Permissions</a></li>
65<li><a href="process.html" class="nav-process">Process</a></li>
66<li><a href="punycode.html" class="nav-punycode">Punycode</a></li>
67<li><a href="querystring.html" class="nav-querystring">Query strings</a></li>
68<li><a href="readline.html" class="nav-readline">Readline</a></li>
69<li><a href="repl.html" class="nav-repl">REPL</a></li>
70<li><a href="report.html" class="nav-report">Report</a></li>
71<li><a href="single-executable-applications.html" class="nav-single-executable-applications">Single executable applications</a></li>
72<li><a href="stream.html" class="nav-stream">Stream</a></li>
73<li><a href="string_decoder.html" class="nav-string_decoder">String decoder</a></li>
74<li><a href="test.html" class="nav-test">Test runner</a></li>
75<li><a href="timers.html" class="nav-timers">Timers</a></li>
76<li><a href="tls.html" class="nav-tls">TLS/SSL</a></li>
77<li><a href="tracing.html" class="nav-tracing">Trace events</a></li>
78<li><a href="tty.html" class="nav-tty">TTY</a></li>
79<li><a href="dgram.html" class="nav-dgram">UDP/datagram</a></li>
80<li><a href="url.html" class="nav-url">URL</a></li>
81<li><a href="util.html" class="nav-util">Utilities</a></li>
82<li><a href="v8.html" class="nav-v8">V8</a></li>
83<li><a href="vm.html" class="nav-vm">VM</a></li>
84<li><a href="wasi.html" class="nav-wasi">WASI</a></li>
85<li><a href="webcrypto.html" class="nav-webcrypto">Web Crypto API</a></li>
86<li><a href="webstreams.html" class="nav-webstreams">Web Streams API</a></li>
87<li><a href="worker_threads.html" class="nav-worker_threads">Worker threads</a></li>
88<li><a href="zlib.html" class="nav-zlib">Zlib</a></li>
89</ul>
90<hr class="line">
91<ul>
92<li><a href="https://github.com/nodejs/node" class="nav-https-github-com-nodejs-node">Code repository and issue tracker</a></li>
93</ul>
94    </div>
95
96    <div id="column1" data-id="addons" class="interior">
97      <header class="header">
98        <div class="header-container">
99          <h1>Node.js v18.18.2 documentation</h1>
100          <button class="theme-toggle-btn" id="theme-toggle-btn" title="Toggle dark mode/light mode" aria-label="Toggle dark mode/light mode" hidden>
101            <svg xmlns="http://www.w3.org/2000/svg" class="icon dark-icon" height="24" width="24">
102              <path fill="none" d="M0 0h24v24H0z" />
103              <path d="M11.1 12.08c-2.33-4.51-.5-8.48.53-10.07C6.27 2.2 1.98 6.59 1.98 12c0 .14.02.28.02.42.62-.27 1.29-.42 2-.42 1.66 0 3.18.83 4.1 2.15A4.01 4.01 0 0111 18c0 1.52-.87 2.83-2.12 3.51.98.32 2.03.5 3.11.5 3.5 0 6.58-1.8 8.37-4.52-2.36.23-6.98-.97-9.26-5.41z"/>
104              <path d="M7 16h-.18C6.4 14.84 5.3 14 4 14c-1.66 0-3 1.34-3 3s1.34 3 3 3h3c1.1 0 2-.9 2-2s-.9-2-2-2z"/>
105            </svg>
106            <svg xmlns="http://www.w3.org/2000/svg" class="icon light-icon" height="24" width="24">
107              <path d="M0 0h24v24H0z" fill="none" />
108              <path d="M6.76 4.84l-1.8-1.79-1.41 1.41 1.79 1.79 1.42-1.41zM4 10.5H1v2h3v-2zm9-9.95h-2V3.5h2V.55zm7.45 3.91l-1.41-1.41-1.79 1.79 1.41 1.41 1.79-1.79zm-3.21 13.7l1.79 1.8 1.41-1.41-1.8-1.79-1.4 1.4zM20 10.5v2h3v-2h-3zm-8-5c-3.31 0-6 2.69-6 6s2.69 6 6 6 6-2.69 6-6-2.69-6-6-6zm-1 16.95h2V19.5h-2v2.95zm-7.45-3.91l1.41 1.41 1.79-1.8-1.41-1.41-1.79 1.8z"/>
109            </svg>
110          </button>
111        </div>
112        <div id="gtoc">
113          <ul>
114            <li class="pinned-header">Node.js v18.18.2</li>
115
116    <li class="picker-header">
117      <a href="#">
118        <span class="collapsed-arrow">&#x25ba;</span><span class="expanded-arrow">&#x25bc;</span>
119        Table of contents
120      </a>
121
122      <div class="picker"><div class="toc"><ul>
123<li><a href="#c-addons">C++ addons</a>
124<ul>
125<li><a href="#hello-world">Hello world</a>
126<ul>
127<li><a href="#context-aware-addons">Context-aware addons</a>
128<ul>
129<li><a href="#worker-support">Worker support</a></li>
130</ul>
131</li>
132<li><a href="#building">Building</a></li>
133<li><a href="#linking-to-libraries-included-with-nodejs">Linking to libraries included with Node.js</a></li>
134<li><a href="#loading-addons-using-require">Loading addons using <code>require()</code></a></li>
135</ul>
136</li>
137<li><a href="#native-abstractions-for-nodejs">Native abstractions for Node.js</a></li>
138<li><span class="stability_2"><a href="#node-api">Node-API</a></span></li>
139<li><a href="#addon-examples">Addon examples</a>
140<ul>
141<li><a href="#function-arguments">Function arguments</a></li>
142<li><a href="#callbacks">Callbacks</a></li>
143<li><a href="#object-factory">Object factory</a></li>
144<li><a href="#function-factory">Function factory</a></li>
145<li><a href="#wrapping-c-objects">Wrapping C++ objects</a></li>
146<li><a href="#factory-of-wrapped-objects">Factory of wrapped objects</a></li>
147<li><a href="#passing-wrapped-objects-around">Passing wrapped objects around</a></li>
148</ul>
149</li>
150</ul>
151</li>
152</ul></div></div>
153    </li>
154
155
156    <li class="picker-header">
157      <a href="#">
158        <span class="collapsed-arrow">&#x25ba;</span><span class="expanded-arrow">&#x25bc;</span>
159        Index
160      </a>
161
162      <div class="picker"><ul>
163<li><a href="documentation.html" class="nav-documentation">About this documentation</a></li>
164<li><a href="synopsis.html" class="nav-synopsis">Usage and example</a></li>
165
166      <li>
167        <a href="index.html">Index</a>
168      </li>
169    </ul>
170
171<hr class="line">
172<ul>
173<li><a href="assert.html" class="nav-assert">Assertion testing</a></li>
174<li><a href="async_context.html" class="nav-async_context">Asynchronous context tracking</a></li>
175<li><a href="async_hooks.html" class="nav-async_hooks">Async hooks</a></li>
176<li><a href="buffer.html" class="nav-buffer">Buffer</a></li>
177<li><a href="addons.html" class="nav-addons active">C++ addons</a></li>
178<li><a href="n-api.html" class="nav-n-api">C/C++ addons with Node-API</a></li>
179<li><a href="embedding.html" class="nav-embedding">C++ embedder API</a></li>
180<li><a href="child_process.html" class="nav-child_process">Child processes</a></li>
181<li><a href="cluster.html" class="nav-cluster">Cluster</a></li>
182<li><a href="cli.html" class="nav-cli">Command-line options</a></li>
183<li><a href="console.html" class="nav-console">Console</a></li>
184<li><a href="corepack.html" class="nav-corepack">Corepack</a></li>
185<li><a href="crypto.html" class="nav-crypto">Crypto</a></li>
186<li><a href="debugger.html" class="nav-debugger">Debugger</a></li>
187<li><a href="deprecations.html" class="nav-deprecations">Deprecated APIs</a></li>
188<li><a href="diagnostics_channel.html" class="nav-diagnostics_channel">Diagnostics Channel</a></li>
189<li><a href="dns.html" class="nav-dns">DNS</a></li>
190<li><a href="domain.html" class="nav-domain">Domain</a></li>
191<li><a href="errors.html" class="nav-errors">Errors</a></li>
192<li><a href="events.html" class="nav-events">Events</a></li>
193<li><a href="fs.html" class="nav-fs">File system</a></li>
194<li><a href="globals.html" class="nav-globals">Globals</a></li>
195<li><a href="http.html" class="nav-http">HTTP</a></li>
196<li><a href="http2.html" class="nav-http2">HTTP/2</a></li>
197<li><a href="https.html" class="nav-https">HTTPS</a></li>
198<li><a href="inspector.html" class="nav-inspector">Inspector</a></li>
199<li><a href="intl.html" class="nav-intl">Internationalization</a></li>
200<li><a href="modules.html" class="nav-modules">Modules: CommonJS modules</a></li>
201<li><a href="esm.html" class="nav-esm">Modules: ECMAScript modules</a></li>
202<li><a href="module.html" class="nav-module">Modules: <code>node:module</code> API</a></li>
203<li><a href="packages.html" class="nav-packages">Modules: Packages</a></li>
204<li><a href="net.html" class="nav-net">Net</a></li>
205<li><a href="os.html" class="nav-os">OS</a></li>
206<li><a href="path.html" class="nav-path">Path</a></li>
207<li><a href="perf_hooks.html" class="nav-perf_hooks">Performance hooks</a></li>
208<li><a href="permissions.html" class="nav-permissions">Permissions</a></li>
209<li><a href="process.html" class="nav-process">Process</a></li>
210<li><a href="punycode.html" class="nav-punycode">Punycode</a></li>
211<li><a href="querystring.html" class="nav-querystring">Query strings</a></li>
212<li><a href="readline.html" class="nav-readline">Readline</a></li>
213<li><a href="repl.html" class="nav-repl">REPL</a></li>
214<li><a href="report.html" class="nav-report">Report</a></li>
215<li><a href="single-executable-applications.html" class="nav-single-executable-applications">Single executable applications</a></li>
216<li><a href="stream.html" class="nav-stream">Stream</a></li>
217<li><a href="string_decoder.html" class="nav-string_decoder">String decoder</a></li>
218<li><a href="test.html" class="nav-test">Test runner</a></li>
219<li><a href="timers.html" class="nav-timers">Timers</a></li>
220<li><a href="tls.html" class="nav-tls">TLS/SSL</a></li>
221<li><a href="tracing.html" class="nav-tracing">Trace events</a></li>
222<li><a href="tty.html" class="nav-tty">TTY</a></li>
223<li><a href="dgram.html" class="nav-dgram">UDP/datagram</a></li>
224<li><a href="url.html" class="nav-url">URL</a></li>
225<li><a href="util.html" class="nav-util">Utilities</a></li>
226<li><a href="v8.html" class="nav-v8">V8</a></li>
227<li><a href="vm.html" class="nav-vm">VM</a></li>
228<li><a href="wasi.html" class="nav-wasi">WASI</a></li>
229<li><a href="webcrypto.html" class="nav-webcrypto">Web Crypto API</a></li>
230<li><a href="webstreams.html" class="nav-webstreams">Web Streams API</a></li>
231<li><a href="worker_threads.html" class="nav-worker_threads">Worker threads</a></li>
232<li><a href="zlib.html" class="nav-zlib">Zlib</a></li>
233</ul>
234<hr class="line">
235<ul>
236<li><a href="https://github.com/nodejs/node" class="nav-https-github-com-nodejs-node">Code repository and issue tracker</a></li>
237</ul></div>
238    </li>
239
240
241    <li class="picker-header">
242      <a href="#">
243        <span class="collapsed-arrow">&#x25ba;</span><span class="expanded-arrow">&#x25bc;</span>
244        Other versions
245      </a>
246      <div class="picker"><ol id="alt-docs"><li><a href="https://nodejs.org/docs/latest-v20.x/api/addons.html">20.x</a></li>
247<li><a href="https://nodejs.org/docs/latest-v19.x/api/addons.html">19.x</a></li>
248<li><a href="https://nodejs.org/docs/latest-v18.x/api/addons.html">18.x <b>LTS</b></a></li>
249<li><a href="https://nodejs.org/docs/latest-v17.x/api/addons.html">17.x</a></li>
250<li><a href="https://nodejs.org/docs/latest-v16.x/api/addons.html">16.x</a></li>
251<li><a href="https://nodejs.org/docs/latest-v15.x/api/addons.html">15.x</a></li>
252<li><a href="https://nodejs.org/docs/latest-v14.x/api/addons.html">14.x</a></li>
253<li><a href="https://nodejs.org/docs/latest-v13.x/api/addons.html">13.x</a></li>
254<li><a href="https://nodejs.org/docs/latest-v12.x/api/addons.html">12.x</a></li>
255<li><a href="https://nodejs.org/docs/latest-v11.x/api/addons.html">11.x</a></li>
256<li><a href="https://nodejs.org/docs/latest-v10.x/api/addons.html">10.x</a></li>
257<li><a href="https://nodejs.org/docs/latest-v9.x/api/addons.html">9.x</a></li>
258<li><a href="https://nodejs.org/docs/latest-v8.x/api/addons.html">8.x</a></li>
259<li><a href="https://nodejs.org/docs/latest-v7.x/api/addons.html">7.x</a></li>
260<li><a href="https://nodejs.org/docs/latest-v6.x/api/addons.html">6.x</a></li>
261<li><a href="https://nodejs.org/docs/latest-v5.x/api/addons.html">5.x</a></li>
262<li><a href="https://nodejs.org/docs/latest-v4.x/api/addons.html">4.x</a></li>
263<li><a href="https://nodejs.org/docs/latest-v0.12.x/api/addons.html">0.12.x</a></li>
264<li><a href="https://nodejs.org/docs/latest-v0.10.x/api/addons.html">0.10.x</a></li></ol></div>
265    </li>
266
267            <li class="picker-header">
268              <a href="#">
269                <span class="collapsed-arrow">&#x25ba;</span><span class="expanded-arrow">&#x25bc;</span>
270                Options
271              </a>
272
273              <div class="picker">
274                <ul>
275                  <li>
276                    <a href="all.html">View on single page</a>
277                  </li>
278                  <li>
279                    <a href="addons.json">View as JSON</a>
280                  </li>
281                  <li class="edit_on_github"><a href="https://github.com/nodejs/node/edit/main/doc/api/addons.md">Edit on GitHub</a></li>
282                </ul>
283              </div>
284            </li>
285          </ul>
286        </div>
287        <hr>
288      </header>
289
290      <details id="toc" open><summary>Table of contents</summary><ul>
291<li><a href="#c-addons">C++ addons</a>
292<ul>
293<li><a href="#hello-world">Hello world</a>
294<ul>
295<li><a href="#context-aware-addons">Context-aware addons</a>
296<ul>
297<li><a href="#worker-support">Worker support</a></li>
298</ul>
299</li>
300<li><a href="#building">Building</a></li>
301<li><a href="#linking-to-libraries-included-with-nodejs">Linking to libraries included with Node.js</a></li>
302<li><a href="#loading-addons-using-require">Loading addons using <code>require()</code></a></li>
303</ul>
304</li>
305<li><a href="#native-abstractions-for-nodejs">Native abstractions for Node.js</a></li>
306<li><span class="stability_2"><a href="#node-api">Node-API</a></span></li>
307<li><a href="#addon-examples">Addon examples</a>
308<ul>
309<li><a href="#function-arguments">Function arguments</a></li>
310<li><a href="#callbacks">Callbacks</a></li>
311<li><a href="#object-factory">Object factory</a></li>
312<li><a href="#function-factory">Function factory</a></li>
313<li><a href="#wrapping-c-objects">Wrapping C++ objects</a></li>
314<li><a href="#factory-of-wrapped-objects">Factory of wrapped objects</a></li>
315<li><a href="#passing-wrapped-objects-around">Passing wrapped objects around</a></li>
316</ul>
317</li>
318</ul>
319</li>
320</ul></details>
321
322      <div id="apicontent">
323        <h2>C++ addons<span><a class="mark" href="#c-addons" id="c-addons">#</a></span><a aria-hidden="true" class="legacy" id="addons_c_addons"></a></h2>
324
325
326<p><em>Addons</em> are dynamically-linked shared objects written in C++. The
327<a href="modules.html#requireid"><code>require()</code></a> function can load addons as ordinary Node.js modules.
328Addons provide an interface between JavaScript and C/C++ libraries.</p>
329<p>There are three options for implementing addons: Node-API, nan, or direct
330use of internal V8, libuv, and Node.js libraries. Unless there is a need for
331direct access to functionality which is not exposed by Node-API, use Node-API.
332Refer to <a href="n-api.html">C/C++ addons with Node-API</a> for more information on
333Node-API.</p>
334<p>When not using Node-API, implementing addons is complicated,
335involving knowledge of several components and APIs:</p>
336<ul>
337<li>
338<p><a href="https://v8.dev/">V8</a>: the C++ library Node.js uses to provide the
339JavaScript implementation. V8 provides the mechanisms for creating objects,
340calling functions, etc. V8's API is documented mostly in the
341<code>v8.h</code> header file (<code>deps/v8/include/v8.h</code> in the Node.js source
342tree), which is also available <a href="https://v8docs.nodesource.com/">online</a>.</p>
343</li>
344<li>
345<p><a href="https://github.com/libuv/libuv">libuv</a>: The C library that implements the Node.js event loop, its worker
346threads and all of the asynchronous behaviors of the platform. It also
347serves as a cross-platform abstraction library, giving easy, POSIX-like
348access across all major operating systems to many common system tasks, such
349as interacting with the file system, sockets, timers, and system events. libuv
350also provides a threading abstraction similar to POSIX threads for
351more sophisticated asynchronous addons that need to move beyond the
352standard event loop. Addon authors should
353avoid blocking the event loop with I/O or other time-intensive tasks by
354offloading work via libuv to non-blocking system operations, worker threads,
355or a custom use of libuv threads.</p>
356</li>
357<li>
358<p>Internal Node.js libraries. Node.js itself exports C++ APIs that addons can
359use, the most important of which is the <code>node::ObjectWrap</code> class.</p>
360</li>
361<li>
362<p>Node.js includes other statically linked libraries including OpenSSL. These
363other libraries are located in the <code>deps/</code> directory in the Node.js source
364tree. Only the libuv, OpenSSL, V8, and zlib symbols are purposefully
365re-exported by Node.js and may be used to various extents by addons. See
366<a href="#linking-to-libraries-included-with-nodejs">Linking to libraries included with Node.js</a> for additional information.</p>
367</li>
368</ul>
369<p>All of the following examples are available for <a href="https://github.com/nodejs/node-addon-examples">download</a> and may
370be used as the starting-point for an addon.</p>
371<section><h3>Hello world<span><a class="mark" href="#hello-world" id="hello-world">#</a></span><a aria-hidden="true" class="legacy" id="addons_hello_world"></a></h3>
372<p>This "Hello world" example is a simple addon, written in C++, that is the
373equivalent of the following JavaScript code:</p>
374<pre><code class="language-js"><span class="hljs-variable language_">module</span>.<span class="hljs-property">exports</span>.<span class="hljs-property">hello</span> = <span class="hljs-function">() =></span> <span class="hljs-string">'world'</span>;</code> <button class="copy-button">copy</button></pre>
375<p>First, create the file <code>hello.cc</code>:</p>
376<pre><code class="language-cpp"><span class="hljs-comment">// hello.cc</span>
377<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&#x3C;node.h></span></span>
378
379<span class="hljs-keyword">namespace</span> demo {
380
381<span class="hljs-keyword">using</span> v8::FunctionCallbackInfo;
382<span class="hljs-keyword">using</span> v8::Isolate;
383<span class="hljs-keyword">using</span> v8::Local;
384<span class="hljs-keyword">using</span> v8::Object;
385<span class="hljs-keyword">using</span> v8::String;
386<span class="hljs-keyword">using</span> v8::Value;
387
388<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">Method</span><span class="hljs-params">(<span class="hljs-type">const</span> FunctionCallbackInfo&#x3C;Value>&#x26; args)</span> </span>{
389  Isolate* isolate = args.<span class="hljs-built_in">GetIsolate</span>();
390  args.<span class="hljs-built_in">GetReturnValue</span>().<span class="hljs-built_in">Set</span>(String::<span class="hljs-built_in">NewFromUtf8</span>(
391      isolate, <span class="hljs-string">"world"</span>).<span class="hljs-built_in">ToLocalChecked</span>());
392}
393
394<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">Initialize</span><span class="hljs-params">(Local&#x3C;Object> exports)</span> </span>{
395  <span class="hljs-built_in">NODE_SET_METHOD</span>(exports, <span class="hljs-string">"hello"</span>, Method);
396}
397
398<span class="hljs-built_in">NODE_MODULE</span>(NODE_GYP_MODULE_NAME, Initialize)
399
400}  <span class="hljs-comment">// namespace demo</span></code> <button class="copy-button">copy</button></pre>
401<p>All Node.js addons must export an initialization function following
402the pattern:</p>
403<pre><code class="language-cpp"><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">Initialize</span><span class="hljs-params">(Local&#x3C;Object> exports)</span></span>;
404<span class="hljs-built_in">NODE_MODULE</span>(NODE_GYP_MODULE_NAME, Initialize)</code> <button class="copy-button">copy</button></pre>
405<p>There is no semi-colon after <code>NODE_MODULE</code> as it's not a function (see
406<code>node.h</code>).</p>
407<p>The <code>module_name</code> must match the filename of the final binary (excluding
408the <code>.node</code> suffix).</p>
409<p>In the <code>hello.cc</code> example, then, the initialization function is <code>Initialize</code>
410and the addon module name is <code>addon</code>.</p>
411<p>When building addons with <code>node-gyp</code>, using the macro <code>NODE_GYP_MODULE_NAME</code> as
412the first parameter of <code>NODE_MODULE()</code> will ensure that the name of the final
413binary will be passed to <code>NODE_MODULE()</code>.</p>
414<p>Addons defined with <code>NODE_MODULE()</code> can not be loaded in multiple contexts or
415multiple threads at the same time.</p>
416<h4>Context-aware addons<span><a class="mark" href="#context-aware-addons" id="context-aware-addons">#</a></span><a aria-hidden="true" class="legacy" id="addons_context_aware_addons"></a></h4>
417<p>There are environments in which Node.js addons may need to be loaded multiple
418times in multiple contexts. For example, the <a href="https://electronjs.org/">Electron</a> runtime runs multiple
419instances of Node.js in a single process. Each instance will have its own
420<code>require()</code> cache, and thus each instance will need a native addon to behave
421correctly when loaded via <code>require()</code>. This means that the addon
422must support multiple initializations.</p>
423<p>A context-aware addon can be constructed by using the macro
424<code>NODE_MODULE_INITIALIZER</code>, which expands to the name of a function which Node.js
425will expect to find when it loads an addon. An addon can thus be initialized as
426in the following example:</p>
427<pre><code class="language-cpp"><span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> v8;
428
429<span class="hljs-keyword">extern</span> <span class="hljs-string">"C"</span> <span class="hljs-function">NODE_MODULE_EXPORT <span class="hljs-type">void</span>
430<span class="hljs-title">NODE_MODULE_INITIALIZER</span><span class="hljs-params">(Local&#x3C;Object> exports,
431                        Local&#x3C;Value> <span class="hljs-keyword">module</span>,
432                        Local&#x3C;Context> context)</span> </span>{
433  <span class="hljs-comment">/* Perform addon initialization steps here. */</span>
434}</code> <button class="copy-button">copy</button></pre>
435<p>Another option is to use the macro <code>NODE_MODULE_INIT()</code>, which will also
436construct a context-aware addon. Unlike <code>NODE_MODULE()</code>, which is used to
437construct an addon around a given addon initializer function,
438<code>NODE_MODULE_INIT()</code> serves as the declaration of such an initializer to be
439followed by a function body.</p>
440<p>The following three variables may be used inside the function body following an
441invocation of <code>NODE_MODULE_INIT()</code>:</p>
442<ul>
443<li><code>Local&#x3C;Object> exports</code>,</li>
444<li><code>Local&#x3C;Value> module</code>, and</li>
445<li><code>Local&#x3C;Context> context</code></li>
446</ul>
447<p>The choice to build a context-aware addon carries with it the responsibility of
448carefully managing global static data. Since the addon may be loaded multiple
449times, potentially even from different threads, any global static data stored
450in the addon must be properly protected, and must not contain any persistent
451references to JavaScript objects. The reason for this is that JavaScript
452objects are only valid in one context, and will likely cause a crash when
453accessed from the wrong context or from a different thread than the one on which
454they were created.</p>
455<p>The context-aware addon can be structured to avoid global static data by
456performing the following steps:</p>
457<ul>
458<li>Define a class which will hold per-addon-instance data and which has a static
459member of the form
460<pre><code class="language-cpp"><span class="hljs-function"><span class="hljs-type">static</span> <span class="hljs-type">void</span> <span class="hljs-title">DeleteInstance</span><span class="hljs-params">(<span class="hljs-type">void</span>* data)</span> </span>{
461  <span class="hljs-comment">// Cast `data` to an instance of the class and delete it.</span>
462}</code> <button class="copy-button">copy</button></pre>
463</li>
464<li>Heap-allocate an instance of this class in the addon initializer. This can be
465accomplished using the <code>new</code> keyword.</li>
466<li>Call <code>node::AddEnvironmentCleanupHook()</code>, passing it the above-created
467instance and a pointer to <code>DeleteInstance()</code>. This will ensure the instance is
468deleted when the environment is torn down.</li>
469<li>Store the instance of the class in a <code>v8::External</code>, and</li>
470<li>Pass the <code>v8::External</code> to all methods exposed to JavaScript by passing it
471to <code>v8::FunctionTemplate::New()</code> or <code>v8::Function::New()</code> which creates the
472native-backed JavaScript functions. The third parameter of
473<code>v8::FunctionTemplate::New()</code> or <code>v8::Function::New()</code>  accepts the
474<code>v8::External</code> and makes it available in the native callback using the
475<code>v8::FunctionCallbackInfo::Data()</code> method.</li>
476</ul>
477<p>This will ensure that the per-addon-instance data reaches each binding that can
478be called from JavaScript. The per-addon-instance data must also be passed into
479any asynchronous callbacks the addon may create.</p>
480<p>The following example illustrates the implementation of a context-aware addon:</p>
481<pre><code class="language-cpp"><span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&#x3C;node.h></span></span>
482
483<span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> v8;
484
485<span class="hljs-keyword">class</span> <span class="hljs-title class_">AddonData</span> {
486 <span class="hljs-keyword">public</span>:
487  <span class="hljs-function"><span class="hljs-keyword">explicit</span> <span class="hljs-title">AddonData</span><span class="hljs-params">(Isolate* isolate)</span>:
488      call_count(<span class="hljs-number">0</span>) {</span>
489    <span class="hljs-comment">// Ensure this per-addon-instance data is deleted at environment cleanup.</span>
490    node::<span class="hljs-built_in">AddEnvironmentCleanupHook</span>(isolate, DeleteInstance, <span class="hljs-keyword">this</span>);
491  }
492
493  <span class="hljs-comment">// Per-addon data.</span>
494  <span class="hljs-type">int</span> call_count;
495
496  <span class="hljs-function"><span class="hljs-type">static</span> <span class="hljs-type">void</span> <span class="hljs-title">DeleteInstance</span><span class="hljs-params">(<span class="hljs-type">void</span>* data)</span> </span>{
497    <span class="hljs-keyword">delete</span> <span class="hljs-built_in">static_cast</span>&#x3C;AddonData*>(data);
498  }
499};
500
501<span class="hljs-function"><span class="hljs-type">static</span> <span class="hljs-type">void</span> <span class="hljs-title">Method</span><span class="hljs-params">(<span class="hljs-type">const</span> v8::FunctionCallbackInfo&#x3C;v8::Value>&#x26; info)</span> </span>{
502  <span class="hljs-comment">// Retrieve the per-addon-instance data.</span>
503  AddonData* data =
504      <span class="hljs-built_in">reinterpret_cast</span>&#x3C;AddonData*>(info.<span class="hljs-built_in">Data</span>().<span class="hljs-built_in">As</span>&#x3C;External>()-><span class="hljs-built_in">Value</span>());
505  data->call_count++;
506  info.<span class="hljs-built_in">GetReturnValue</span>().<span class="hljs-built_in">Set</span>((<span class="hljs-type">double</span>)data->call_count);
507}
508
509<span class="hljs-comment">// Initialize this addon to be context-aware.</span>
510<span class="hljs-built_in">NODE_MODULE_INIT</span>(<span class="hljs-comment">/* exports, module, context */</span>) {
511  Isolate* isolate = context-><span class="hljs-built_in">GetIsolate</span>();
512
513  <span class="hljs-comment">// Create a new instance of `AddonData` for this instance of the addon and</span>
514  <span class="hljs-comment">// tie its life cycle to that of the Node.js environment.</span>
515  AddonData* data = <span class="hljs-keyword">new</span> <span class="hljs-built_in">AddonData</span>(isolate);
516
517  <span class="hljs-comment">// Wrap the data in a `v8::External` so we can pass it to the method we</span>
518  <span class="hljs-comment">// expose.</span>
519  Local&#x3C;External> external = External::<span class="hljs-built_in">New</span>(isolate, data);
520
521  <span class="hljs-comment">// Expose the method `Method` to JavaScript, and make sure it receives the</span>
522  <span class="hljs-comment">// per-addon-instance data we created above by passing `external` as the</span>
523  <span class="hljs-comment">// third parameter to the `FunctionTemplate` constructor.</span>
524  exports-><span class="hljs-built_in">Set</span>(context,
525               String::<span class="hljs-built_in">NewFromUtf8</span>(isolate, <span class="hljs-string">"method"</span>).<span class="hljs-built_in">ToLocalChecked</span>(),
526               FunctionTemplate::<span class="hljs-built_in">New</span>(isolate, Method, external)
527                  -><span class="hljs-built_in">GetFunction</span>(context).<span class="hljs-built_in">ToLocalChecked</span>()).<span class="hljs-built_in">FromJust</span>();
528}</code> <button class="copy-button">copy</button></pre>
529<h5>Worker support<span><a class="mark" href="#worker-support" id="worker-support">#</a></span><a aria-hidden="true" class="legacy" id="addons_worker_support"></a></h5>
530<div class="api_metadata">
531<details class="changelog"><summary>History</summary>
532<table>
533<tbody><tr><th>Version</th><th>Changes</th></tr>
534<tr><td>v14.8.0, v12.19.0</td>
535<td><p>Cleanup hooks may now be asynchronous.</p></td></tr>
536</tbody></table>
537</details>
538</div>
539<p>In order to be loaded from multiple Node.js environments,
540such as a main thread and a Worker thread, an add-on needs to either:</p>
541<ul>
542<li>Be an Node-API addon, or</li>
543<li>Be declared as context-aware using <code>NODE_MODULE_INIT()</code> as described above</li>
544</ul>
545<p>In order to support <a href="worker_threads.html#class-worker"><code>Worker</code></a> threads, addons need to clean up any resources
546they may have allocated when such a thread exists. This can be achieved through
547the usage of the <code>AddEnvironmentCleanupHook()</code> function:</p>
548<pre><code class="language-cpp"><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">AddEnvironmentCleanupHook</span><span class="hljs-params">(v8::Isolate* isolate,
549                               <span class="hljs-type">void</span> (*fun)(<span class="hljs-type">void</span>* arg),
550                               <span class="hljs-type">void</span>* arg)</span></span>;</code> <button class="copy-button">copy</button></pre>
551<p>This function adds a hook that will run before a given Node.js instance shuts
552down. If necessary, such hooks can be removed before they are run using
553<code>RemoveEnvironmentCleanupHook()</code>, which has the same signature. Callbacks are
554run in last-in first-out order.</p>
555<p>If necessary, there is an additional pair of <code>AddEnvironmentCleanupHook()</code>
556and <code>RemoveEnvironmentCleanupHook()</code> overloads, where the cleanup hook takes a
557callback function. This can be used for shutting down asynchronous resources,
558such as any libuv handles registered by the addon.</p>
559<p>The following <code>addon.cc</code> uses <code>AddEnvironmentCleanupHook</code>:</p>
560<pre><code class="language-cpp"><span class="hljs-comment">// addon.cc</span>
561<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&#x3C;node.h></span></span>
562<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&#x3C;assert.h></span></span>
563<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&#x3C;stdlib.h></span></span>
564
565<span class="hljs-keyword">using</span> node::AddEnvironmentCleanupHook;
566<span class="hljs-keyword">using</span> v8::HandleScope;
567<span class="hljs-keyword">using</span> v8::Isolate;
568<span class="hljs-keyword">using</span> v8::Local;
569<span class="hljs-keyword">using</span> v8::Object;
570
571<span class="hljs-comment">// Note: In a real-world application, do not rely on static/global data.</span>
572<span class="hljs-type">static</span> <span class="hljs-type">char</span> cookie[] = <span class="hljs-string">"yum yum"</span>;
573<span class="hljs-type">static</span> <span class="hljs-type">int</span> cleanup_cb1_called = <span class="hljs-number">0</span>;
574<span class="hljs-type">static</span> <span class="hljs-type">int</span> cleanup_cb2_called = <span class="hljs-number">0</span>;
575
576<span class="hljs-function"><span class="hljs-type">static</span> <span class="hljs-type">void</span> <span class="hljs-title">cleanup_cb1</span><span class="hljs-params">(<span class="hljs-type">void</span>* arg)</span> </span>{
577  Isolate* isolate = <span class="hljs-built_in">static_cast</span>&#x3C;Isolate*>(arg);
578  <span class="hljs-function">HandleScope <span class="hljs-title">scope</span><span class="hljs-params">(isolate)</span></span>;
579  Local&#x3C;Object> obj = Object::<span class="hljs-built_in">New</span>(isolate);
580  <span class="hljs-built_in">assert</span>(!obj.<span class="hljs-built_in">IsEmpty</span>());  <span class="hljs-comment">// assert VM is still alive</span>
581  <span class="hljs-built_in">assert</span>(obj-><span class="hljs-built_in">IsObject</span>());
582  cleanup_cb1_called++;
583}
584
585<span class="hljs-function"><span class="hljs-type">static</span> <span class="hljs-type">void</span> <span class="hljs-title">cleanup_cb2</span><span class="hljs-params">(<span class="hljs-type">void</span>* arg)</span> </span>{
586  <span class="hljs-built_in">assert</span>(arg == <span class="hljs-built_in">static_cast</span>&#x3C;<span class="hljs-type">void</span>*>(cookie));
587  cleanup_cb2_called++;
588}
589
590<span class="hljs-function"><span class="hljs-type">static</span> <span class="hljs-type">void</span> <span class="hljs-title">sanity_check</span><span class="hljs-params">(<span class="hljs-type">void</span>*)</span> </span>{
591  <span class="hljs-built_in">assert</span>(cleanup_cb1_called == <span class="hljs-number">1</span>);
592  <span class="hljs-built_in">assert</span>(cleanup_cb2_called == <span class="hljs-number">1</span>);
593}
594
595<span class="hljs-comment">// Initialize this addon to be context-aware.</span>
596<span class="hljs-built_in">NODE_MODULE_INIT</span>(<span class="hljs-comment">/* exports, module, context */</span>) {
597  Isolate* isolate = context-><span class="hljs-built_in">GetIsolate</span>();
598
599  <span class="hljs-built_in">AddEnvironmentCleanupHook</span>(isolate, sanity_check, <span class="hljs-literal">nullptr</span>);
600  <span class="hljs-built_in">AddEnvironmentCleanupHook</span>(isolate, cleanup_cb2, cookie);
601  <span class="hljs-built_in">AddEnvironmentCleanupHook</span>(isolate, cleanup_cb1, isolate);
602}</code> <button class="copy-button">copy</button></pre>
603<p>Test in JavaScript by running:</p>
604<pre><code class="language-js"><span class="hljs-comment">// test.js</span>
605<span class="hljs-built_in">require</span>(<span class="hljs-string">'./build/Release/addon'</span>);</code> <button class="copy-button">copy</button></pre>
606<h4>Building<span><a class="mark" href="#building" id="building">#</a></span><a aria-hidden="true" class="legacy" id="addons_building"></a></h4>
607<p>Once the source code has been written, it must be compiled into the binary
608<code>addon.node</code> file. To do so, create a file called <code>binding.gyp</code> in the
609top-level of the project describing the build configuration of the module
610using a JSON-like format. This file is used by <a href="https://github.com/nodejs/node-gyp">node-gyp</a>, a tool written
611specifically to compile Node.js addons.</p>
612<pre><code class="language-json"><span class="hljs-punctuation">{</span>
613  <span class="hljs-attr">"targets"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
614    <span class="hljs-punctuation">{</span>
615      <span class="hljs-attr">"target_name"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"addon"</span><span class="hljs-punctuation">,</span>
616      <span class="hljs-attr">"sources"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span> <span class="hljs-string">"hello.cc"</span> <span class="hljs-punctuation">]</span>
617    <span class="hljs-punctuation">}</span>
618  <span class="hljs-punctuation">]</span>
619<span class="hljs-punctuation">}</span></code> <button class="copy-button">copy</button></pre>
620<p>A version of the <code>node-gyp</code> utility is bundled and distributed with
621Node.js as part of <code>npm</code>. This version is not made directly available for
622developers to use and is intended only to support the ability to use the
623<code>npm install</code> command to compile and install addons. Developers who wish to
624use <code>node-gyp</code> directly can install it using the command
625<code>npm install -g node-gyp</code>. See the <code>node-gyp</code> <a href="https://github.com/nodejs/node-gyp#installation">installation instructions</a> for
626more information, including platform-specific requirements.</p>
627<p>Once the <code>binding.gyp</code> file has been created, use <code>node-gyp configure</code> to
628generate the appropriate project build files for the current platform. This
629will generate either a <code>Makefile</code> (on Unix platforms) or a <code>vcxproj</code> file
630(on Windows) in the <code>build/</code> directory.</p>
631<p>Next, invoke the <code>node-gyp build</code> command to generate the compiled <code>addon.node</code>
632file. This will be put into the <code>build/Release/</code> directory.</p>
633<p>When using <code>npm install</code> to install a Node.js addon, npm uses its own bundled
634version of <code>node-gyp</code> to perform this same set of actions, generating a
635compiled version of the addon for the user's platform on demand.</p>
636<p>Once built, the binary addon can be used from within Node.js by pointing
637<a href="modules.html#requireid"><code>require()</code></a> to the built <code>addon.node</code> module:</p>
638<pre><code class="language-js"><span class="hljs-comment">// hello.js</span>
639<span class="hljs-keyword">const</span> addon = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./build/Release/addon'</span>);
640
641<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(addon.<span class="hljs-title function_">hello</span>());
642<span class="hljs-comment">// Prints: 'world'</span></code> <button class="copy-button">copy</button></pre>
643<p>Because the exact path to the compiled addon binary can vary depending on how
644it is compiled (i.e. sometimes it may be in <code>./build/Debug/</code>), addons can use
645the <a href="https://github.com/TooTallNate/node-bindings">bindings</a> package to load the compiled module.</p>
646<p>While the <code>bindings</code> package implementation is more sophisticated in how it
647locates addon modules, it is essentially using a <code>try…catch</code> pattern similar to:</p>
648<pre><code class="language-js"><span class="hljs-keyword">try</span> {
649  <span class="hljs-keyword">return</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">'./build/Release/addon.node'</span>);
650} <span class="hljs-keyword">catch</span> (err) {
651  <span class="hljs-keyword">return</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">'./build/Debug/addon.node'</span>);
652}</code> <button class="copy-button">copy</button></pre>
653<h4>Linking to libraries included with Node.js<span><a class="mark" href="#linking-to-libraries-included-with-nodejs" id="linking-to-libraries-included-with-nodejs">#</a></span><a aria-hidden="true" class="legacy" id="addons_linking_to_libraries_included_with_node_js"></a></h4>
654<p>Node.js uses statically linked libraries such as V8, libuv, and OpenSSL. All
655addons are required to link to V8 and may link to any of the other dependencies
656as well. Typically, this is as simple as including the appropriate
657<code>#include &#x3C;...></code> statements (e.g. <code>#include &#x3C;v8.h></code>) and <code>node-gyp</code> will locate
658the appropriate headers automatically. However, there are a few caveats to be
659aware of:</p>
660<ul>
661<li>
662<p>When <code>node-gyp</code> runs, it will detect the specific release version of Node.js
663and download either the full source tarball or just the headers. If the full
664source is downloaded, addons will have complete access to the full set of
665Node.js dependencies. However, if only the Node.js headers are downloaded,
666then only the symbols exported by Node.js will be available.</p>
667</li>
668<li>
669<p><code>node-gyp</code> can be run using the <code>--nodedir</code> flag pointing at a local Node.js
670source image. Using this option, the addon will have access to the full set of
671dependencies.</p>
672</li>
673</ul>
674<h4>Loading addons using <code>require()</code><span><a class="mark" href="#loading-addons-using-require" id="loading-addons-using-require">#</a></span><a aria-hidden="true" class="legacy" id="addons_loading_addons_using_require"></a></h4>
675<p>The filename extension of the compiled addon binary is <code>.node</code> (as opposed
676to <code>.dll</code> or <code>.so</code>). The <a href="modules.html#requireid"><code>require()</code></a> function is written to look for
677files with the <code>.node</code> file extension and initialize those as dynamically-linked
678libraries.</p>
679<p>When calling <a href="modules.html#requireid"><code>require()</code></a>, the <code>.node</code> extension can usually be
680omitted and Node.js will still find and initialize the addon. One caveat,
681however, is that Node.js will first attempt to locate and load modules or
682JavaScript files that happen to share the same base name. For instance, if
683there is a file <code>addon.js</code> in the same directory as the binary <code>addon.node</code>,
684then <a href="modules.html#requireid"><code>require('addon')</code></a> will give precedence to the <code>addon.js</code> file
685and load it instead.</p>
686</section><section><h3>Native abstractions for Node.js<span><a class="mark" href="#native-abstractions-for-nodejs" id="native-abstractions-for-nodejs">#</a></span><a aria-hidden="true" class="legacy" id="addons_native_abstractions_for_node_js"></a></h3>
687<p>Each of the examples illustrated in this document directly use the
688Node.js and V8 APIs for implementing addons. The V8 API can, and has, changed
689dramatically from one V8 release to the next (and one major Node.js release to
690the next). With each change, addons may need to be updated and recompiled in
691order to continue functioning. The Node.js release schedule is designed to
692minimize the frequency and impact of such changes but there is little that
693Node.js can do to ensure stability of the V8 APIs.</p>
694<p>The <a href="https://github.com/nodejs/nan">Native Abstractions for Node.js</a> (or <code>nan</code>) provide a set of tools that
695addon developers are recommended to use to keep compatibility between past and
696future releases of V8 and Node.js. See the <code>nan</code> <a href="https://github.com/nodejs/nan/tree/HEAD/examples/">examples</a> for an
697illustration of how it can be used.</p>
698</section><section><h3>Node-API<span><a class="mark" href="#node-api" id="node-api">#</a></span><a aria-hidden="true" class="legacy" id="addons_node_api"></a></h3>
699<p></p><div class="api_stability api_stability_2"><a href="documentation.html#stability-index">Stability: 2</a> - Stable</div><p></p>
700<p>Node-API is an API for building native addons. It is independent from
701the underlying JavaScript runtime (e.g. V8) and is maintained as part of
702Node.js itself. This API will be Application Binary Interface (ABI) stable
703across versions of Node.js. It is intended to insulate addons from
704changes in the underlying JavaScript engine and allow modules
705compiled for one version to run on later versions of Node.js without
706recompilation. Addons are built/packaged with the same approach/tools
707outlined in this document (node-gyp, etc.). The only difference is the
708set of APIs that are used by the native code. Instead of using the V8
709or <a href="https://github.com/nodejs/nan">Native Abstractions for Node.js</a> APIs, the functions available
710in the Node-API are used.</p>
711<p>Creating and maintaining an addon that benefits from the ABI stability
712provided by Node-API carries with it certain
713<a href="n-api.html#implications-of-abi-stability">implementation considerations</a>.</p>
714<p>To use Node-API in the above "Hello world" example, replace the content of
715<code>hello.cc</code> with the following. All other instructions remain the same.</p>
716<pre><code class="language-cpp"><span class="hljs-comment">// hello.cc using Node-API</span>
717<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&#x3C;node_api.h></span></span>
718
719<span class="hljs-keyword">namespace</span> demo {
720
721<span class="hljs-function">napi_value <span class="hljs-title">Method</span><span class="hljs-params">(napi_env env, napi_callback_info args)</span> </span>{
722  napi_value greeting;
723  napi_status status;
724
725  status = <span class="hljs-built_in">napi_create_string_utf8</span>(env, <span class="hljs-string">"world"</span>, NAPI_AUTO_LENGTH, &#x26;greeting);
726  <span class="hljs-keyword">if</span> (status != napi_ok) <span class="hljs-keyword">return</span> <span class="hljs-literal">nullptr</span>;
727  <span class="hljs-keyword">return</span> greeting;
728}
729
730<span class="hljs-function">napi_value <span class="hljs-title">init</span><span class="hljs-params">(napi_env env, napi_value exports)</span> </span>{
731  napi_status status;
732  napi_value fn;
733
734  status = <span class="hljs-built_in">napi_create_function</span>(env, <span class="hljs-literal">nullptr</span>, <span class="hljs-number">0</span>, Method, <span class="hljs-literal">nullptr</span>, &#x26;fn);
735  <span class="hljs-keyword">if</span> (status != napi_ok) <span class="hljs-keyword">return</span> <span class="hljs-literal">nullptr</span>;
736
737  status = <span class="hljs-built_in">napi_set_named_property</span>(env, exports, <span class="hljs-string">"hello"</span>, fn);
738  <span class="hljs-keyword">if</span> (status != napi_ok) <span class="hljs-keyword">return</span> <span class="hljs-literal">nullptr</span>;
739  <span class="hljs-keyword">return</span> exports;
740}
741
742<span class="hljs-built_in">NAPI_MODULE</span>(NODE_GYP_MODULE_NAME, init)
743
744}  <span class="hljs-comment">// namespace demo</span></code> <button class="copy-button">copy</button></pre>
745<p>The functions available and how to use them are documented in
746<a href="n-api.html">C/C++ addons with Node-API</a>.</p>
747</section><section><h3>Addon examples<span><a class="mark" href="#addon-examples" id="addon-examples">#</a></span><a aria-hidden="true" class="legacy" id="addons_addon_examples"></a></h3>
748<p>Following are some example addons intended to help developers get started. The
749examples use the V8 APIs. Refer to the online <a href="https://v8docs.nodesource.com/">V8 reference</a>
750for help with the various V8 calls, and V8's <a href="https://v8.dev/docs/embed">Embedder's Guide</a> for an
751explanation of several concepts used such as handles, scopes, function
752templates, etc.</p>
753<p>Each of these examples using the following <code>binding.gyp</code> file:</p>
754<pre><code class="language-json"><span class="hljs-punctuation">{</span>
755  <span class="hljs-attr">"targets"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
756    <span class="hljs-punctuation">{</span>
757      <span class="hljs-attr">"target_name"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"addon"</span><span class="hljs-punctuation">,</span>
758      <span class="hljs-attr">"sources"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span> <span class="hljs-string">"addon.cc"</span> <span class="hljs-punctuation">]</span>
759    <span class="hljs-punctuation">}</span>
760  <span class="hljs-punctuation">]</span>
761<span class="hljs-punctuation">}</span></code> <button class="copy-button">copy</button></pre>
762<p>In cases where there is more than one <code>.cc</code> file, simply add the additional
763filename to the <code>sources</code> array:</p>
764<pre><code class="language-json"><span class="hljs-attr">"sources"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-string">"addon.cc"</span><span class="hljs-punctuation">,</span> <span class="hljs-string">"myexample.cc"</span><span class="hljs-punctuation">]</span></code> <button class="copy-button">copy</button></pre>
765<p>Once the <code>binding.gyp</code> file is ready, the example addons can be configured and
766built using <code>node-gyp</code>:</p>
767<pre><code class="language-console"><span class="hljs-meta prompt_">$ </span><span class="language-bash">node-gyp configure build</span></code> <button class="copy-button">copy</button></pre>
768<h4>Function arguments<span><a class="mark" href="#function-arguments" id="function-arguments">#</a></span><a aria-hidden="true" class="legacy" id="addons_function_arguments"></a></h4>
769<p>Addons will typically expose objects and functions that can be accessed from
770JavaScript running within Node.js. When functions are invoked from JavaScript,
771the input arguments and return value must be mapped to and from the C/C++
772code.</p>
773<p>The following example illustrates how to read function arguments passed from
774JavaScript and how to return a result:</p>
775<pre><code class="language-cpp"><span class="hljs-comment">// addon.cc</span>
776<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&#x3C;node.h></span></span>
777
778<span class="hljs-keyword">namespace</span> demo {
779
780<span class="hljs-keyword">using</span> v8::Exception;
781<span class="hljs-keyword">using</span> v8::FunctionCallbackInfo;
782<span class="hljs-keyword">using</span> v8::Isolate;
783<span class="hljs-keyword">using</span> v8::Local;
784<span class="hljs-keyword">using</span> v8::Number;
785<span class="hljs-keyword">using</span> v8::Object;
786<span class="hljs-keyword">using</span> v8::String;
787<span class="hljs-keyword">using</span> v8::Value;
788
789<span class="hljs-comment">// This is the implementation of the "add" method</span>
790<span class="hljs-comment">// Input arguments are passed using the</span>
791<span class="hljs-comment">// const FunctionCallbackInfo&#x3C;Value>&#x26; args struct</span>
792<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">Add</span><span class="hljs-params">(<span class="hljs-type">const</span> FunctionCallbackInfo&#x3C;Value>&#x26; args)</span> </span>{
793  Isolate* isolate = args.<span class="hljs-built_in">GetIsolate</span>();
794
795  <span class="hljs-comment">// Check the number of arguments passed.</span>
796  <span class="hljs-keyword">if</span> (args.<span class="hljs-built_in">Length</span>() &#x3C; <span class="hljs-number">2</span>) {
797    <span class="hljs-comment">// Throw an Error that is passed back to JavaScript</span>
798    isolate-><span class="hljs-built_in">ThrowException</span>(Exception::<span class="hljs-built_in">TypeError</span>(
799        String::<span class="hljs-built_in">NewFromUtf8</span>(isolate,
800                            <span class="hljs-string">"Wrong number of arguments"</span>).<span class="hljs-built_in">ToLocalChecked</span>()));
801    <span class="hljs-keyword">return</span>;
802  }
803
804  <span class="hljs-comment">// Check the argument types</span>
805  <span class="hljs-keyword">if</span> (!args[<span class="hljs-number">0</span>]-><span class="hljs-built_in">IsNumber</span>() || !args[<span class="hljs-number">1</span>]-><span class="hljs-built_in">IsNumber</span>()) {
806    isolate-><span class="hljs-built_in">ThrowException</span>(Exception::<span class="hljs-built_in">TypeError</span>(
807        String::<span class="hljs-built_in">NewFromUtf8</span>(isolate,
808                            <span class="hljs-string">"Wrong arguments"</span>).<span class="hljs-built_in">ToLocalChecked</span>()));
809    <span class="hljs-keyword">return</span>;
810  }
811
812  <span class="hljs-comment">// Perform the operation</span>
813  <span class="hljs-type">double</span> value =
814      args[<span class="hljs-number">0</span>].<span class="hljs-built_in">As</span>&#x3C;Number>()-><span class="hljs-built_in">Value</span>() + args[<span class="hljs-number">1</span>].<span class="hljs-built_in">As</span>&#x3C;Number>()-><span class="hljs-built_in">Value</span>();
815  Local&#x3C;Number> num = Number::<span class="hljs-built_in">New</span>(isolate, value);
816
817  <span class="hljs-comment">// Set the return value (using the passed in</span>
818  <span class="hljs-comment">// FunctionCallbackInfo&#x3C;Value>&#x26;)</span>
819  args.<span class="hljs-built_in">GetReturnValue</span>().<span class="hljs-built_in">Set</span>(num);
820}
821
822<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">Init</span><span class="hljs-params">(Local&#x3C;Object> exports)</span> </span>{
823  <span class="hljs-built_in">NODE_SET_METHOD</span>(exports, <span class="hljs-string">"add"</span>, Add);
824}
825
826<span class="hljs-built_in">NODE_MODULE</span>(NODE_GYP_MODULE_NAME, Init)
827
828}  <span class="hljs-comment">// namespace demo</span></code> <button class="copy-button">copy</button></pre>
829<p>Once compiled, the example addon can be required and used from within Node.js:</p>
830<pre><code class="language-js"><span class="hljs-comment">// test.js</span>
831<span class="hljs-keyword">const</span> addon = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./build/Release/addon'</span>);
832
833<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'This should be eight:'</span>, addon.<span class="hljs-title function_">add</span>(<span class="hljs-number">3</span>, <span class="hljs-number">5</span>));</code> <button class="copy-button">copy</button></pre>
834<h4>Callbacks<span><a class="mark" href="#callbacks" id="callbacks">#</a></span><a aria-hidden="true" class="legacy" id="addons_callbacks"></a></h4>
835<p>It is common practice within addons to pass JavaScript functions to a C++
836function and execute them from there. The following example illustrates how
837to invoke such callbacks:</p>
838<pre><code class="language-cpp"><span class="hljs-comment">// addon.cc</span>
839<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&#x3C;node.h></span></span>
840
841<span class="hljs-keyword">namespace</span> demo {
842
843<span class="hljs-keyword">using</span> v8::Context;
844<span class="hljs-keyword">using</span> v8::Function;
845<span class="hljs-keyword">using</span> v8::FunctionCallbackInfo;
846<span class="hljs-keyword">using</span> v8::Isolate;
847<span class="hljs-keyword">using</span> v8::Local;
848<span class="hljs-keyword">using</span> v8::Null;
849<span class="hljs-keyword">using</span> v8::Object;
850<span class="hljs-keyword">using</span> v8::String;
851<span class="hljs-keyword">using</span> v8::Value;
852
853<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">RunCallback</span><span class="hljs-params">(<span class="hljs-type">const</span> FunctionCallbackInfo&#x3C;Value>&#x26; args)</span> </span>{
854  Isolate* isolate = args.<span class="hljs-built_in">GetIsolate</span>();
855  Local&#x3C;Context> context = isolate-><span class="hljs-built_in">GetCurrentContext</span>();
856  Local&#x3C;Function> cb = Local&#x3C;Function>::<span class="hljs-built_in">Cast</span>(args[<span class="hljs-number">0</span>]);
857  <span class="hljs-type">const</span> <span class="hljs-type">unsigned</span> argc = <span class="hljs-number">1</span>;
858  Local&#x3C;Value> argv[argc] = {
859      String::<span class="hljs-built_in">NewFromUtf8</span>(isolate,
860                          <span class="hljs-string">"hello world"</span>).<span class="hljs-built_in">ToLocalChecked</span>() };
861  cb-><span class="hljs-built_in">Call</span>(context, <span class="hljs-built_in">Null</span>(isolate), argc, argv).<span class="hljs-built_in">ToLocalChecked</span>();
862}
863
864<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">Init</span><span class="hljs-params">(Local&#x3C;Object> exports, Local&#x3C;Object> <span class="hljs-keyword">module</span>)</span> </span>{
865  <span class="hljs-built_in">NODE_SET_METHOD</span>(<span class="hljs-keyword">module</span>, <span class="hljs-string">"exports"</span>, RunCallback);
866}
867
868<span class="hljs-built_in">NODE_MODULE</span>(NODE_GYP_MODULE_NAME, Init)
869
870}  <span class="hljs-comment">// namespace demo</span></code> <button class="copy-button">copy</button></pre>
871<p>This example uses a two-argument form of <code>Init()</code> that receives the full
872<code>module</code> object as the second argument. This allows the addon to completely
873overwrite <code>exports</code> with a single function instead of adding the function as a
874property of <code>exports</code>.</p>
875<p>To test it, run the following JavaScript:</p>
876<pre><code class="language-js"><span class="hljs-comment">// test.js</span>
877<span class="hljs-keyword">const</span> addon = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./build/Release/addon'</span>);
878
879<span class="hljs-title function_">addon</span>(<span class="hljs-function">(<span class="hljs-params">msg</span>) =></span> {
880  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(msg);
881<span class="hljs-comment">// Prints: 'hello world'</span>
882});</code> <button class="copy-button">copy</button></pre>
883<p>In this example, the callback function is invoked synchronously.</p>
884<h4>Object factory<span><a class="mark" href="#object-factory" id="object-factory">#</a></span><a aria-hidden="true" class="legacy" id="addons_object_factory"></a></h4>
885<p>Addons can create and return new objects from within a C++ function as
886illustrated in the following example. An object is created and returned with a
887property <code>msg</code> that echoes the string passed to <code>createObject()</code>:</p>
888<pre><code class="language-cpp"><span class="hljs-comment">// addon.cc</span>
889<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&#x3C;node.h></span></span>
890
891<span class="hljs-keyword">namespace</span> demo {
892
893<span class="hljs-keyword">using</span> v8::Context;
894<span class="hljs-keyword">using</span> v8::FunctionCallbackInfo;
895<span class="hljs-keyword">using</span> v8::Isolate;
896<span class="hljs-keyword">using</span> v8::Local;
897<span class="hljs-keyword">using</span> v8::Object;
898<span class="hljs-keyword">using</span> v8::String;
899<span class="hljs-keyword">using</span> v8::Value;
900
901<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">CreateObject</span><span class="hljs-params">(<span class="hljs-type">const</span> FunctionCallbackInfo&#x3C;Value>&#x26; args)</span> </span>{
902  Isolate* isolate = args.<span class="hljs-built_in">GetIsolate</span>();
903  Local&#x3C;Context> context = isolate-><span class="hljs-built_in">GetCurrentContext</span>();
904
905  Local&#x3C;Object> obj = Object::<span class="hljs-built_in">New</span>(isolate);
906  obj-><span class="hljs-built_in">Set</span>(context,
907           String::<span class="hljs-built_in">NewFromUtf8</span>(isolate,
908                               <span class="hljs-string">"msg"</span>).<span class="hljs-built_in">ToLocalChecked</span>(),
909                               args[<span class="hljs-number">0</span>]-><span class="hljs-built_in">ToString</span>(context).<span class="hljs-built_in">ToLocalChecked</span>())
910           .<span class="hljs-built_in">FromJust</span>();
911
912  args.<span class="hljs-built_in">GetReturnValue</span>().<span class="hljs-built_in">Set</span>(obj);
913}
914
915<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">Init</span><span class="hljs-params">(Local&#x3C;Object> exports, Local&#x3C;Object> <span class="hljs-keyword">module</span>)</span> </span>{
916  <span class="hljs-built_in">NODE_SET_METHOD</span>(<span class="hljs-keyword">module</span>, <span class="hljs-string">"exports"</span>, CreateObject);
917}
918
919<span class="hljs-built_in">NODE_MODULE</span>(NODE_GYP_MODULE_NAME, Init)
920
921}  <span class="hljs-comment">// namespace demo</span></code> <button class="copy-button">copy</button></pre>
922<p>To test it in JavaScript:</p>
923<pre><code class="language-js"><span class="hljs-comment">// test.js</span>
924<span class="hljs-keyword">const</span> addon = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./build/Release/addon'</span>);
925
926<span class="hljs-keyword">const</span> obj1 = <span class="hljs-title function_">addon</span>(<span class="hljs-string">'hello'</span>);
927<span class="hljs-keyword">const</span> obj2 = <span class="hljs-title function_">addon</span>(<span class="hljs-string">'world'</span>);
928<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(obj1.<span class="hljs-property">msg</span>, obj2.<span class="hljs-property">msg</span>);
929<span class="hljs-comment">// Prints: 'hello world'</span></code> <button class="copy-button">copy</button></pre>
930<h4>Function factory<span><a class="mark" href="#function-factory" id="function-factory">#</a></span><a aria-hidden="true" class="legacy" id="addons_function_factory"></a></h4>
931<p>Another common scenario is creating JavaScript functions that wrap C++
932functions and returning those back to JavaScript:</p>
933<pre><code class="language-cpp"><span class="hljs-comment">// addon.cc</span>
934<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&#x3C;node.h></span></span>
935
936<span class="hljs-keyword">namespace</span> demo {
937
938<span class="hljs-keyword">using</span> v8::Context;
939<span class="hljs-keyword">using</span> v8::Function;
940<span class="hljs-keyword">using</span> v8::FunctionCallbackInfo;
941<span class="hljs-keyword">using</span> v8::FunctionTemplate;
942<span class="hljs-keyword">using</span> v8::Isolate;
943<span class="hljs-keyword">using</span> v8::Local;
944<span class="hljs-keyword">using</span> v8::Object;
945<span class="hljs-keyword">using</span> v8::String;
946<span class="hljs-keyword">using</span> v8::Value;
947
948<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">MyFunction</span><span class="hljs-params">(<span class="hljs-type">const</span> FunctionCallbackInfo&#x3C;Value>&#x26; args)</span> </span>{
949  Isolate* isolate = args.<span class="hljs-built_in">GetIsolate</span>();
950  args.<span class="hljs-built_in">GetReturnValue</span>().<span class="hljs-built_in">Set</span>(String::<span class="hljs-built_in">NewFromUtf8</span>(
951      isolate, <span class="hljs-string">"hello world"</span>).<span class="hljs-built_in">ToLocalChecked</span>());
952}
953
954<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">CreateFunction</span><span class="hljs-params">(<span class="hljs-type">const</span> FunctionCallbackInfo&#x3C;Value>&#x26; args)</span> </span>{
955  Isolate* isolate = args.<span class="hljs-built_in">GetIsolate</span>();
956
957  Local&#x3C;Context> context = isolate-><span class="hljs-built_in">GetCurrentContext</span>();
958  Local&#x3C;FunctionTemplate> tpl = FunctionTemplate::<span class="hljs-built_in">New</span>(isolate, MyFunction);
959  Local&#x3C;Function> fn = tpl-><span class="hljs-built_in">GetFunction</span>(context).<span class="hljs-built_in">ToLocalChecked</span>();
960
961  <span class="hljs-comment">// omit this to make it anonymous</span>
962  fn-><span class="hljs-built_in">SetName</span>(String::<span class="hljs-built_in">NewFromUtf8</span>(
963      isolate, <span class="hljs-string">"theFunction"</span>).<span class="hljs-built_in">ToLocalChecked</span>());
964
965  args.<span class="hljs-built_in">GetReturnValue</span>().<span class="hljs-built_in">Set</span>(fn);
966}
967
968<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">Init</span><span class="hljs-params">(Local&#x3C;Object> exports, Local&#x3C;Object> <span class="hljs-keyword">module</span>)</span> </span>{
969  <span class="hljs-built_in">NODE_SET_METHOD</span>(<span class="hljs-keyword">module</span>, <span class="hljs-string">"exports"</span>, CreateFunction);
970}
971
972<span class="hljs-built_in">NODE_MODULE</span>(NODE_GYP_MODULE_NAME, Init)
973
974}  <span class="hljs-comment">// namespace demo</span></code> <button class="copy-button">copy</button></pre>
975<p>To test:</p>
976<pre><code class="language-js"><span class="hljs-comment">// test.js</span>
977<span class="hljs-keyword">const</span> addon = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./build/Release/addon'</span>);
978
979<span class="hljs-keyword">const</span> fn = <span class="hljs-title function_">addon</span>();
980<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title function_">fn</span>());
981<span class="hljs-comment">// Prints: 'hello world'</span></code> <button class="copy-button">copy</button></pre>
982<h4>Wrapping C++ objects<span><a class="mark" href="#wrapping-c-objects" id="wrapping-c-objects">#</a></span><a aria-hidden="true" class="legacy" id="addons_wrapping_c_objects"></a></h4>
983<p>It is also possible to wrap C++ objects/classes in a way that allows new
984instances to be created using the JavaScript <code>new</code> operator:</p>
985<pre><code class="language-cpp"><span class="hljs-comment">// addon.cc</span>
986<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&#x3C;node.h></span></span>
987<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">"myobject.h"</span></span>
988
989<span class="hljs-keyword">namespace</span> demo {
990
991<span class="hljs-keyword">using</span> v8::Local;
992<span class="hljs-keyword">using</span> v8::Object;
993
994<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">InitAll</span><span class="hljs-params">(Local&#x3C;Object> exports)</span> </span>{
995  MyObject::<span class="hljs-built_in">Init</span>(exports);
996}
997
998<span class="hljs-built_in">NODE_MODULE</span>(NODE_GYP_MODULE_NAME, InitAll)
999
1000}  <span class="hljs-comment">// namespace demo</span></code> <button class="copy-button">copy</button></pre>
1001<p>Then, in <code>myobject.h</code>, the wrapper class inherits from <code>node::ObjectWrap</code>:</p>
1002<pre><code class="language-cpp"><span class="hljs-comment">// myobject.h</span>
1003<span class="hljs-meta">#<span class="hljs-keyword">ifndef</span> MYOBJECT_H</span>
1004<span class="hljs-meta">#<span class="hljs-keyword">define</span> MYOBJECT_H</span>
1005
1006<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&#x3C;node.h></span></span>
1007<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&#x3C;node_object_wrap.h></span></span>
1008
1009<span class="hljs-keyword">namespace</span> demo {
1010
1011<span class="hljs-keyword">class</span> <span class="hljs-title class_">MyObject</span> : <span class="hljs-keyword">public</span> node::ObjectWrap {
1012 <span class="hljs-keyword">public</span>:
1013  <span class="hljs-function"><span class="hljs-type">static</span> <span class="hljs-type">void</span> <span class="hljs-title">Init</span><span class="hljs-params">(v8::Local&#x3C;v8::Object> exports)</span></span>;
1014
1015 <span class="hljs-keyword">private</span>:
1016  <span class="hljs-function"><span class="hljs-keyword">explicit</span> <span class="hljs-title">MyObject</span><span class="hljs-params">(<span class="hljs-type">double</span> value = <span class="hljs-number">0</span>)</span></span>;
1017  ~<span class="hljs-built_in">MyObject</span>();
1018
1019  <span class="hljs-function"><span class="hljs-type">static</span> <span class="hljs-type">void</span> <span class="hljs-title">New</span><span class="hljs-params">(<span class="hljs-type">const</span> v8::FunctionCallbackInfo&#x3C;v8::Value>&#x26; args)</span></span>;
1020  <span class="hljs-function"><span class="hljs-type">static</span> <span class="hljs-type">void</span> <span class="hljs-title">PlusOne</span><span class="hljs-params">(<span class="hljs-type">const</span> v8::FunctionCallbackInfo&#x3C;v8::Value>&#x26; args)</span></span>;
1021
1022  <span class="hljs-type">double</span> value_;
1023};
1024
1025}  <span class="hljs-comment">// namespace demo</span>
1026
1027<span class="hljs-meta">#<span class="hljs-keyword">endif</span></span></code> <button class="copy-button">copy</button></pre>
1028<p>In <code>myobject.cc</code>, implement the various methods that are to be exposed.
1029Below, the method <code>plusOne()</code> is exposed by adding it to the constructor's
1030prototype:</p>
1031<pre><code class="language-cpp"><span class="hljs-comment">// myobject.cc</span>
1032<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">"myobject.h"</span></span>
1033
1034<span class="hljs-keyword">namespace</span> demo {
1035
1036<span class="hljs-keyword">using</span> v8::Context;
1037<span class="hljs-keyword">using</span> v8::Function;
1038<span class="hljs-keyword">using</span> v8::FunctionCallbackInfo;
1039<span class="hljs-keyword">using</span> v8::FunctionTemplate;
1040<span class="hljs-keyword">using</span> v8::Isolate;
1041<span class="hljs-keyword">using</span> v8::Local;
1042<span class="hljs-keyword">using</span> v8::Number;
1043<span class="hljs-keyword">using</span> v8::Object;
1044<span class="hljs-keyword">using</span> v8::ObjectTemplate;
1045<span class="hljs-keyword">using</span> v8::String;
1046<span class="hljs-keyword">using</span> v8::Value;
1047
1048MyObject::<span class="hljs-built_in">MyObject</span>(<span class="hljs-type">double</span> value) : <span class="hljs-built_in">value_</span>(value) {
1049}
1050
1051MyObject::~<span class="hljs-built_in">MyObject</span>() {
1052}
1053
1054<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">MyObject::Init</span><span class="hljs-params">(Local&#x3C;Object> exports)</span> </span>{
1055  Isolate* isolate = exports-><span class="hljs-built_in">GetIsolate</span>();
1056  Local&#x3C;Context> context = isolate-><span class="hljs-built_in">GetCurrentContext</span>();
1057
1058  Local&#x3C;ObjectTemplate> addon_data_tpl = ObjectTemplate::<span class="hljs-built_in">New</span>(isolate);
1059  addon_data_tpl-><span class="hljs-built_in">SetInternalFieldCount</span>(<span class="hljs-number">1</span>);  <span class="hljs-comment">// 1 field for the MyObject::New()</span>
1060  Local&#x3C;Object> addon_data =
1061      addon_data_tpl-><span class="hljs-built_in">NewInstance</span>(context).<span class="hljs-built_in">ToLocalChecked</span>();
1062
1063  <span class="hljs-comment">// Prepare constructor template</span>
1064  Local&#x3C;FunctionTemplate> tpl = FunctionTemplate::<span class="hljs-built_in">New</span>(isolate, New, addon_data);
1065  tpl-><span class="hljs-built_in">SetClassName</span>(String::<span class="hljs-built_in">NewFromUtf8</span>(isolate, <span class="hljs-string">"MyObject"</span>).<span class="hljs-built_in">ToLocalChecked</span>());
1066  tpl-><span class="hljs-built_in">InstanceTemplate</span>()-><span class="hljs-built_in">SetInternalFieldCount</span>(<span class="hljs-number">1</span>);
1067
1068  <span class="hljs-comment">// Prototype</span>
1069  <span class="hljs-built_in">NODE_SET_PROTOTYPE_METHOD</span>(tpl, <span class="hljs-string">"plusOne"</span>, PlusOne);
1070
1071  Local&#x3C;Function> constructor = tpl-><span class="hljs-built_in">GetFunction</span>(context).<span class="hljs-built_in">ToLocalChecked</span>();
1072  addon_data-><span class="hljs-built_in">SetInternalField</span>(<span class="hljs-number">0</span>, constructor);
1073  exports-><span class="hljs-built_in">Set</span>(context, String::<span class="hljs-built_in">NewFromUtf8</span>(
1074      isolate, <span class="hljs-string">"MyObject"</span>).<span class="hljs-built_in">ToLocalChecked</span>(),
1075      constructor).<span class="hljs-built_in">FromJust</span>();
1076}
1077
1078<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">MyObject::New</span><span class="hljs-params">(<span class="hljs-type">const</span> FunctionCallbackInfo&#x3C;Value>&#x26; args)</span> </span>{
1079  Isolate* isolate = args.<span class="hljs-built_in">GetIsolate</span>();
1080  Local&#x3C;Context> context = isolate-><span class="hljs-built_in">GetCurrentContext</span>();
1081
1082  <span class="hljs-keyword">if</span> (args.<span class="hljs-built_in">IsConstructCall</span>()) {
1083    <span class="hljs-comment">// Invoked as constructor: `new MyObject(...)`</span>
1084    <span class="hljs-type">double</span> value = args[<span class="hljs-number">0</span>]-><span class="hljs-built_in">IsUndefined</span>() ?
1085        <span class="hljs-number">0</span> : args[<span class="hljs-number">0</span>]-><span class="hljs-built_in">NumberValue</span>(context).<span class="hljs-built_in">FromMaybe</span>(<span class="hljs-number">0</span>);
1086    MyObject* obj = <span class="hljs-keyword">new</span> <span class="hljs-built_in">MyObject</span>(value);
1087    obj-><span class="hljs-built_in">Wrap</span>(args.<span class="hljs-built_in">This</span>());
1088    args.<span class="hljs-built_in">GetReturnValue</span>().<span class="hljs-built_in">Set</span>(args.<span class="hljs-built_in">This</span>());
1089  } <span class="hljs-keyword">else</span> {
1090    <span class="hljs-comment">// Invoked as plain function `MyObject(...)`, turn into construct call.</span>
1091    <span class="hljs-type">const</span> <span class="hljs-type">int</span> argc = <span class="hljs-number">1</span>;
1092    Local&#x3C;Value> argv[argc] = { args[<span class="hljs-number">0</span>] };
1093    Local&#x3C;Function> cons =
1094        args.<span class="hljs-built_in">Data</span>().<span class="hljs-built_in">As</span>&#x3C;Object>()-><span class="hljs-built_in">GetInternalField</span>(<span class="hljs-number">0</span>).<span class="hljs-built_in">As</span>&#x3C;Function>();
1095    Local&#x3C;Object> result =
1096        cons-><span class="hljs-built_in">NewInstance</span>(context, argc, argv).<span class="hljs-built_in">ToLocalChecked</span>();
1097    args.<span class="hljs-built_in">GetReturnValue</span>().<span class="hljs-built_in">Set</span>(result);
1098  }
1099}
1100
1101<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">MyObject::PlusOne</span><span class="hljs-params">(<span class="hljs-type">const</span> FunctionCallbackInfo&#x3C;Value>&#x26; args)</span> </span>{
1102  Isolate* isolate = args.<span class="hljs-built_in">GetIsolate</span>();
1103
1104  MyObject* obj = ObjectWrap::<span class="hljs-built_in">Unwrap</span>&#x3C;MyObject>(args.<span class="hljs-built_in">Holder</span>());
1105  obj->value_ += <span class="hljs-number">1</span>;
1106
1107  args.<span class="hljs-built_in">GetReturnValue</span>().<span class="hljs-built_in">Set</span>(Number::<span class="hljs-built_in">New</span>(isolate, obj->value_));
1108}
1109
1110}  <span class="hljs-comment">// namespace demo</span></code> <button class="copy-button">copy</button></pre>
1111<p>To build this example, the <code>myobject.cc</code> file must be added to the
1112<code>binding.gyp</code>:</p>
1113<pre><code class="language-json"><span class="hljs-punctuation">{</span>
1114  <span class="hljs-attr">"targets"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
1115    <span class="hljs-punctuation">{</span>
1116      <span class="hljs-attr">"target_name"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"addon"</span><span class="hljs-punctuation">,</span>
1117      <span class="hljs-attr">"sources"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
1118        <span class="hljs-string">"addon.cc"</span><span class="hljs-punctuation">,</span>
1119        <span class="hljs-string">"myobject.cc"</span>
1120      <span class="hljs-punctuation">]</span>
1121    <span class="hljs-punctuation">}</span>
1122  <span class="hljs-punctuation">]</span>
1123<span class="hljs-punctuation">}</span></code> <button class="copy-button">copy</button></pre>
1124<p>Test it with:</p>
1125<pre><code class="language-js"><span class="hljs-comment">// test.js</span>
1126<span class="hljs-keyword">const</span> addon = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./build/Release/addon'</span>);
1127
1128<span class="hljs-keyword">const</span> obj = <span class="hljs-keyword">new</span> addon.<span class="hljs-title class_">MyObject</span>(<span class="hljs-number">10</span>);
1129<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(obj.<span class="hljs-title function_">plusOne</span>());
1130<span class="hljs-comment">// Prints: 11</span>
1131<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(obj.<span class="hljs-title function_">plusOne</span>());
1132<span class="hljs-comment">// Prints: 12</span>
1133<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(obj.<span class="hljs-title function_">plusOne</span>());
1134<span class="hljs-comment">// Prints: 13</span></code> <button class="copy-button">copy</button></pre>
1135<p>The destructor for a wrapper object will run when the object is
1136garbage-collected. For destructor testing, there are command-line flags that
1137can be used to make it possible to force garbage collection. These flags are
1138provided by the underlying V8 JavaScript engine. They are subject to change
1139or removal at any time. They are not documented by Node.js or V8, and they
1140should never be used outside of testing.</p>
1141<p>During shutdown of the process or worker threads destructors are not called
1142by the JS engine. Therefore it's the responsibility of the user to track
1143these objects and ensure proper destruction to avoid resource leaks.</p>
1144<h4>Factory of wrapped objects<span><a class="mark" href="#factory-of-wrapped-objects" id="factory-of-wrapped-objects">#</a></span><a aria-hidden="true" class="legacy" id="addons_factory_of_wrapped_objects"></a></h4>
1145<p>Alternatively, it is possible to use a factory pattern to avoid explicitly
1146creating object instances using the JavaScript <code>new</code> operator:</p>
1147<pre><code class="language-js"><span class="hljs-keyword">const</span> obj = addon.<span class="hljs-title function_">createObject</span>();
1148<span class="hljs-comment">// instead of:</span>
1149<span class="hljs-comment">// const obj = new addon.Object();</span></code> <button class="copy-button">copy</button></pre>
1150<p>First, the <code>createObject()</code> method is implemented in <code>addon.cc</code>:</p>
1151<pre><code class="language-cpp"><span class="hljs-comment">// addon.cc</span>
1152<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&#x3C;node.h></span></span>
1153<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">"myobject.h"</span></span>
1154
1155<span class="hljs-keyword">namespace</span> demo {
1156
1157<span class="hljs-keyword">using</span> v8::FunctionCallbackInfo;
1158<span class="hljs-keyword">using</span> v8::Isolate;
1159<span class="hljs-keyword">using</span> v8::Local;
1160<span class="hljs-keyword">using</span> v8::Object;
1161<span class="hljs-keyword">using</span> v8::String;
1162<span class="hljs-keyword">using</span> v8::Value;
1163
1164<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">CreateObject</span><span class="hljs-params">(<span class="hljs-type">const</span> FunctionCallbackInfo&#x3C;Value>&#x26; args)</span> </span>{
1165  MyObject::<span class="hljs-built_in">NewInstance</span>(args);
1166}
1167
1168<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">InitAll</span><span class="hljs-params">(Local&#x3C;Object> exports, Local&#x3C;Object> <span class="hljs-keyword">module</span>)</span> </span>{
1169  MyObject::<span class="hljs-built_in">Init</span>(exports-><span class="hljs-built_in">GetIsolate</span>());
1170
1171  <span class="hljs-built_in">NODE_SET_METHOD</span>(<span class="hljs-keyword">module</span>, <span class="hljs-string">"exports"</span>, CreateObject);
1172}
1173
1174<span class="hljs-built_in">NODE_MODULE</span>(NODE_GYP_MODULE_NAME, InitAll)
1175
1176}  <span class="hljs-comment">// namespace demo</span></code> <button class="copy-button">copy</button></pre>
1177<p>In <code>myobject.h</code>, the static method <code>NewInstance()</code> is added to handle
1178instantiating the object. This method takes the place of using <code>new</code> in
1179JavaScript:</p>
1180<pre><code class="language-cpp"><span class="hljs-comment">// myobject.h</span>
1181<span class="hljs-meta">#<span class="hljs-keyword">ifndef</span> MYOBJECT_H</span>
1182<span class="hljs-meta">#<span class="hljs-keyword">define</span> MYOBJECT_H</span>
1183
1184<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&#x3C;node.h></span></span>
1185<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&#x3C;node_object_wrap.h></span></span>
1186
1187<span class="hljs-keyword">namespace</span> demo {
1188
1189<span class="hljs-keyword">class</span> <span class="hljs-title class_">MyObject</span> : <span class="hljs-keyword">public</span> node::ObjectWrap {
1190 <span class="hljs-keyword">public</span>:
1191  <span class="hljs-function"><span class="hljs-type">static</span> <span class="hljs-type">void</span> <span class="hljs-title">Init</span><span class="hljs-params">(v8::Isolate* isolate)</span></span>;
1192  <span class="hljs-function"><span class="hljs-type">static</span> <span class="hljs-type">void</span> <span class="hljs-title">NewInstance</span><span class="hljs-params">(<span class="hljs-type">const</span> v8::FunctionCallbackInfo&#x3C;v8::Value>&#x26; args)</span></span>;
1193
1194 <span class="hljs-keyword">private</span>:
1195  <span class="hljs-function"><span class="hljs-keyword">explicit</span> <span class="hljs-title">MyObject</span><span class="hljs-params">(<span class="hljs-type">double</span> value = <span class="hljs-number">0</span>)</span></span>;
1196  ~<span class="hljs-built_in">MyObject</span>();
1197
1198  <span class="hljs-function"><span class="hljs-type">static</span> <span class="hljs-type">void</span> <span class="hljs-title">New</span><span class="hljs-params">(<span class="hljs-type">const</span> v8::FunctionCallbackInfo&#x3C;v8::Value>&#x26; args)</span></span>;
1199  <span class="hljs-function"><span class="hljs-type">static</span> <span class="hljs-type">void</span> <span class="hljs-title">PlusOne</span><span class="hljs-params">(<span class="hljs-type">const</span> v8::FunctionCallbackInfo&#x3C;v8::Value>&#x26; args)</span></span>;
1200  <span class="hljs-type">static</span> v8::Global&#x3C;v8::Function> constructor;
1201  <span class="hljs-type">double</span> value_;
1202};
1203
1204}  <span class="hljs-comment">// namespace demo</span>
1205
1206<span class="hljs-meta">#<span class="hljs-keyword">endif</span></span></code> <button class="copy-button">copy</button></pre>
1207<p>The implementation in <code>myobject.cc</code> is similar to the previous example:</p>
1208<pre><code class="language-cpp"><span class="hljs-comment">// myobject.cc</span>
1209<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&#x3C;node.h></span></span>
1210<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">"myobject.h"</span></span>
1211
1212<span class="hljs-keyword">namespace</span> demo {
1213
1214<span class="hljs-keyword">using</span> node::AddEnvironmentCleanupHook;
1215<span class="hljs-keyword">using</span> v8::Context;
1216<span class="hljs-keyword">using</span> v8::Function;
1217<span class="hljs-keyword">using</span> v8::FunctionCallbackInfo;
1218<span class="hljs-keyword">using</span> v8::FunctionTemplate;
1219<span class="hljs-keyword">using</span> v8::Global;
1220<span class="hljs-keyword">using</span> v8::Isolate;
1221<span class="hljs-keyword">using</span> v8::Local;
1222<span class="hljs-keyword">using</span> v8::Number;
1223<span class="hljs-keyword">using</span> v8::Object;
1224<span class="hljs-keyword">using</span> v8::String;
1225<span class="hljs-keyword">using</span> v8::Value;
1226
1227<span class="hljs-comment">// Warning! This is not thread-safe, this addon cannot be used for worker</span>
1228<span class="hljs-comment">// threads.</span>
1229Global&#x3C;Function> MyObject::constructor;
1230
1231MyObject::<span class="hljs-built_in">MyObject</span>(<span class="hljs-type">double</span> value) : <span class="hljs-built_in">value_</span>(value) {
1232}
1233
1234MyObject::~<span class="hljs-built_in">MyObject</span>() {
1235}
1236
1237<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">MyObject::Init</span><span class="hljs-params">(Isolate* isolate)</span> </span>{
1238  <span class="hljs-comment">// Prepare constructor template</span>
1239  Local&#x3C;FunctionTemplate> tpl = FunctionTemplate::<span class="hljs-built_in">New</span>(isolate, New);
1240  tpl-><span class="hljs-built_in">SetClassName</span>(String::<span class="hljs-built_in">NewFromUtf8</span>(isolate, <span class="hljs-string">"MyObject"</span>).<span class="hljs-built_in">ToLocalChecked</span>());
1241  tpl-><span class="hljs-built_in">InstanceTemplate</span>()-><span class="hljs-built_in">SetInternalFieldCount</span>(<span class="hljs-number">1</span>);
1242
1243  <span class="hljs-comment">// Prototype</span>
1244  <span class="hljs-built_in">NODE_SET_PROTOTYPE_METHOD</span>(tpl, <span class="hljs-string">"plusOne"</span>, PlusOne);
1245
1246  Local&#x3C;Context> context = isolate-><span class="hljs-built_in">GetCurrentContext</span>();
1247  constructor.<span class="hljs-built_in">Reset</span>(isolate, tpl-><span class="hljs-built_in">GetFunction</span>(context).<span class="hljs-built_in">ToLocalChecked</span>());
1248
1249  <span class="hljs-built_in">AddEnvironmentCleanupHook</span>(isolate, [](<span class="hljs-type">void</span>*) {
1250    constructor.<span class="hljs-built_in">Reset</span>();
1251  }, <span class="hljs-literal">nullptr</span>);
1252}
1253
1254<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">MyObject::New</span><span class="hljs-params">(<span class="hljs-type">const</span> FunctionCallbackInfo&#x3C;Value>&#x26; args)</span> </span>{
1255  Isolate* isolate = args.<span class="hljs-built_in">GetIsolate</span>();
1256  Local&#x3C;Context> context = isolate-><span class="hljs-built_in">GetCurrentContext</span>();
1257
1258  <span class="hljs-keyword">if</span> (args.<span class="hljs-built_in">IsConstructCall</span>()) {
1259    <span class="hljs-comment">// Invoked as constructor: `new MyObject(...)`</span>
1260    <span class="hljs-type">double</span> value = args[<span class="hljs-number">0</span>]-><span class="hljs-built_in">IsUndefined</span>() ?
1261        <span class="hljs-number">0</span> : args[<span class="hljs-number">0</span>]-><span class="hljs-built_in">NumberValue</span>(context).<span class="hljs-built_in">FromMaybe</span>(<span class="hljs-number">0</span>);
1262    MyObject* obj = <span class="hljs-keyword">new</span> <span class="hljs-built_in">MyObject</span>(value);
1263    obj-><span class="hljs-built_in">Wrap</span>(args.<span class="hljs-built_in">This</span>());
1264    args.<span class="hljs-built_in">GetReturnValue</span>().<span class="hljs-built_in">Set</span>(args.<span class="hljs-built_in">This</span>());
1265  } <span class="hljs-keyword">else</span> {
1266    <span class="hljs-comment">// Invoked as plain function `MyObject(...)`, turn into construct call.</span>
1267    <span class="hljs-type">const</span> <span class="hljs-type">int</span> argc = <span class="hljs-number">1</span>;
1268    Local&#x3C;Value> argv[argc] = { args[<span class="hljs-number">0</span>] };
1269    Local&#x3C;Function> cons = Local&#x3C;Function>::<span class="hljs-built_in">New</span>(isolate, constructor);
1270    Local&#x3C;Object> instance =
1271        cons-><span class="hljs-built_in">NewInstance</span>(context, argc, argv).<span class="hljs-built_in">ToLocalChecked</span>();
1272    args.<span class="hljs-built_in">GetReturnValue</span>().<span class="hljs-built_in">Set</span>(instance);
1273  }
1274}
1275
1276<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">MyObject::NewInstance</span><span class="hljs-params">(<span class="hljs-type">const</span> FunctionCallbackInfo&#x3C;Value>&#x26; args)</span> </span>{
1277  Isolate* isolate = args.<span class="hljs-built_in">GetIsolate</span>();
1278
1279  <span class="hljs-type">const</span> <span class="hljs-type">unsigned</span> argc = <span class="hljs-number">1</span>;
1280  Local&#x3C;Value> argv[argc] = { args[<span class="hljs-number">0</span>] };
1281  Local&#x3C;Function> cons = Local&#x3C;Function>::<span class="hljs-built_in">New</span>(isolate, constructor);
1282  Local&#x3C;Context> context = isolate-><span class="hljs-built_in">GetCurrentContext</span>();
1283  Local&#x3C;Object> instance =
1284      cons-><span class="hljs-built_in">NewInstance</span>(context, argc, argv).<span class="hljs-built_in">ToLocalChecked</span>();
1285
1286  args.<span class="hljs-built_in">GetReturnValue</span>().<span class="hljs-built_in">Set</span>(instance);
1287}
1288
1289<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">MyObject::PlusOne</span><span class="hljs-params">(<span class="hljs-type">const</span> FunctionCallbackInfo&#x3C;Value>&#x26; args)</span> </span>{
1290  Isolate* isolate = args.<span class="hljs-built_in">GetIsolate</span>();
1291
1292  MyObject* obj = ObjectWrap::<span class="hljs-built_in">Unwrap</span>&#x3C;MyObject>(args.<span class="hljs-built_in">Holder</span>());
1293  obj->value_ += <span class="hljs-number">1</span>;
1294
1295  args.<span class="hljs-built_in">GetReturnValue</span>().<span class="hljs-built_in">Set</span>(Number::<span class="hljs-built_in">New</span>(isolate, obj->value_));
1296}
1297
1298}  <span class="hljs-comment">// namespace demo</span></code> <button class="copy-button">copy</button></pre>
1299<p>Once again, to build this example, the <code>myobject.cc</code> file must be added to the
1300<code>binding.gyp</code>:</p>
1301<pre><code class="language-json"><span class="hljs-punctuation">{</span>
1302  <span class="hljs-attr">"targets"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
1303    <span class="hljs-punctuation">{</span>
1304      <span class="hljs-attr">"target_name"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"addon"</span><span class="hljs-punctuation">,</span>
1305      <span class="hljs-attr">"sources"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
1306        <span class="hljs-string">"addon.cc"</span><span class="hljs-punctuation">,</span>
1307        <span class="hljs-string">"myobject.cc"</span>
1308      <span class="hljs-punctuation">]</span>
1309    <span class="hljs-punctuation">}</span>
1310  <span class="hljs-punctuation">]</span>
1311<span class="hljs-punctuation">}</span></code> <button class="copy-button">copy</button></pre>
1312<p>Test it with:</p>
1313<pre><code class="language-js"><span class="hljs-comment">// test.js</span>
1314<span class="hljs-keyword">const</span> createObject = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./build/Release/addon'</span>);
1315
1316<span class="hljs-keyword">const</span> obj = <span class="hljs-title function_">createObject</span>(<span class="hljs-number">10</span>);
1317<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(obj.<span class="hljs-title function_">plusOne</span>());
1318<span class="hljs-comment">// Prints: 11</span>
1319<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(obj.<span class="hljs-title function_">plusOne</span>());
1320<span class="hljs-comment">// Prints: 12</span>
1321<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(obj.<span class="hljs-title function_">plusOne</span>());
1322<span class="hljs-comment">// Prints: 13</span>
1323
1324<span class="hljs-keyword">const</span> obj2 = <span class="hljs-title function_">createObject</span>(<span class="hljs-number">20</span>);
1325<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(obj2.<span class="hljs-title function_">plusOne</span>());
1326<span class="hljs-comment">// Prints: 21</span>
1327<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(obj2.<span class="hljs-title function_">plusOne</span>());
1328<span class="hljs-comment">// Prints: 22</span>
1329<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(obj2.<span class="hljs-title function_">plusOne</span>());
1330<span class="hljs-comment">// Prints: 23</span></code> <button class="copy-button">copy</button></pre>
1331<h4>Passing wrapped objects around<span><a class="mark" href="#passing-wrapped-objects-around" id="passing-wrapped-objects-around">#</a></span><a aria-hidden="true" class="legacy" id="addons_passing_wrapped_objects_around"></a></h4>
1332<p>In addition to wrapping and returning C++ objects, it is possible to pass
1333wrapped objects around by unwrapping them with the Node.js helper function
1334<code>node::ObjectWrap::Unwrap</code>. The following examples shows a function <code>add()</code>
1335that can take two <code>MyObject</code> objects as input arguments:</p>
1336<pre><code class="language-cpp"><span class="hljs-comment">// addon.cc</span>
1337<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&#x3C;node.h></span></span>
1338<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&#x3C;node_object_wrap.h></span></span>
1339<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">"myobject.h"</span></span>
1340
1341<span class="hljs-keyword">namespace</span> demo {
1342
1343<span class="hljs-keyword">using</span> v8::Context;
1344<span class="hljs-keyword">using</span> v8::FunctionCallbackInfo;
1345<span class="hljs-keyword">using</span> v8::Isolate;
1346<span class="hljs-keyword">using</span> v8::Local;
1347<span class="hljs-keyword">using</span> v8::Number;
1348<span class="hljs-keyword">using</span> v8::Object;
1349<span class="hljs-keyword">using</span> v8::String;
1350<span class="hljs-keyword">using</span> v8::Value;
1351
1352<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">CreateObject</span><span class="hljs-params">(<span class="hljs-type">const</span> FunctionCallbackInfo&#x3C;Value>&#x26; args)</span> </span>{
1353  MyObject::<span class="hljs-built_in">NewInstance</span>(args);
1354}
1355
1356<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">Add</span><span class="hljs-params">(<span class="hljs-type">const</span> FunctionCallbackInfo&#x3C;Value>&#x26; args)</span> </span>{
1357  Isolate* isolate = args.<span class="hljs-built_in">GetIsolate</span>();
1358  Local&#x3C;Context> context = isolate-><span class="hljs-built_in">GetCurrentContext</span>();
1359
1360  MyObject* obj1 = node::ObjectWrap::<span class="hljs-built_in">Unwrap</span>&#x3C;MyObject>(
1361      args[<span class="hljs-number">0</span>]-><span class="hljs-built_in">ToObject</span>(context).<span class="hljs-built_in">ToLocalChecked</span>());
1362  MyObject* obj2 = node::ObjectWrap::<span class="hljs-built_in">Unwrap</span>&#x3C;MyObject>(
1363      args[<span class="hljs-number">1</span>]-><span class="hljs-built_in">ToObject</span>(context).<span class="hljs-built_in">ToLocalChecked</span>());
1364
1365  <span class="hljs-type">double</span> sum = obj1-><span class="hljs-built_in">value</span>() + obj2-><span class="hljs-built_in">value</span>();
1366  args.<span class="hljs-built_in">GetReturnValue</span>().<span class="hljs-built_in">Set</span>(Number::<span class="hljs-built_in">New</span>(isolate, sum));
1367}
1368
1369<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">InitAll</span><span class="hljs-params">(Local&#x3C;Object> exports)</span> </span>{
1370  MyObject::<span class="hljs-built_in">Init</span>(exports-><span class="hljs-built_in">GetIsolate</span>());
1371
1372  <span class="hljs-built_in">NODE_SET_METHOD</span>(exports, <span class="hljs-string">"createObject"</span>, CreateObject);
1373  <span class="hljs-built_in">NODE_SET_METHOD</span>(exports, <span class="hljs-string">"add"</span>, Add);
1374}
1375
1376<span class="hljs-built_in">NODE_MODULE</span>(NODE_GYP_MODULE_NAME, InitAll)
1377
1378}  <span class="hljs-comment">// namespace demo</span></code> <button class="copy-button">copy</button></pre>
1379<p>In <code>myobject.h</code>, a new public method is added to allow access to private values
1380after unwrapping the object.</p>
1381<pre><code class="language-cpp"><span class="hljs-comment">// myobject.h</span>
1382<span class="hljs-meta">#<span class="hljs-keyword">ifndef</span> MYOBJECT_H</span>
1383<span class="hljs-meta">#<span class="hljs-keyword">define</span> MYOBJECT_H</span>
1384
1385<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&#x3C;node.h></span></span>
1386<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&#x3C;node_object_wrap.h></span></span>
1387
1388<span class="hljs-keyword">namespace</span> demo {
1389
1390<span class="hljs-keyword">class</span> <span class="hljs-title class_">MyObject</span> : <span class="hljs-keyword">public</span> node::ObjectWrap {
1391 <span class="hljs-keyword">public</span>:
1392  <span class="hljs-function"><span class="hljs-type">static</span> <span class="hljs-type">void</span> <span class="hljs-title">Init</span><span class="hljs-params">(v8::Isolate* isolate)</span></span>;
1393  <span class="hljs-function"><span class="hljs-type">static</span> <span class="hljs-type">void</span> <span class="hljs-title">NewInstance</span><span class="hljs-params">(<span class="hljs-type">const</span> v8::FunctionCallbackInfo&#x3C;v8::Value>&#x26; args)</span></span>;
1394  <span class="hljs-function"><span class="hljs-keyword">inline</span> <span class="hljs-type">double</span> <span class="hljs-title">value</span><span class="hljs-params">()</span> <span class="hljs-type">const</span> </span>{ <span class="hljs-keyword">return</span> value_; }
1395
1396 <span class="hljs-keyword">private</span>:
1397  <span class="hljs-function"><span class="hljs-keyword">explicit</span> <span class="hljs-title">MyObject</span><span class="hljs-params">(<span class="hljs-type">double</span> value = <span class="hljs-number">0</span>)</span></span>;
1398  ~<span class="hljs-built_in">MyObject</span>();
1399
1400  <span class="hljs-function"><span class="hljs-type">static</span> <span class="hljs-type">void</span> <span class="hljs-title">New</span><span class="hljs-params">(<span class="hljs-type">const</span> v8::FunctionCallbackInfo&#x3C;v8::Value>&#x26; args)</span></span>;
1401  <span class="hljs-type">static</span> v8::Global&#x3C;v8::Function> constructor;
1402  <span class="hljs-type">double</span> value_;
1403};
1404
1405}  <span class="hljs-comment">// namespace demo</span>
1406
1407<span class="hljs-meta">#<span class="hljs-keyword">endif</span></span></code> <button class="copy-button">copy</button></pre>
1408<p>The implementation of <code>myobject.cc</code> is similar to before:</p>
1409<pre><code class="language-cpp"><span class="hljs-comment">// myobject.cc</span>
1410<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&#x3C;node.h></span></span>
1411<span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">"myobject.h"</span></span>
1412
1413<span class="hljs-keyword">namespace</span> demo {
1414
1415<span class="hljs-keyword">using</span> node::AddEnvironmentCleanupHook;
1416<span class="hljs-keyword">using</span> v8::Context;
1417<span class="hljs-keyword">using</span> v8::Function;
1418<span class="hljs-keyword">using</span> v8::FunctionCallbackInfo;
1419<span class="hljs-keyword">using</span> v8::FunctionTemplate;
1420<span class="hljs-keyword">using</span> v8::Global;
1421<span class="hljs-keyword">using</span> v8::Isolate;
1422<span class="hljs-keyword">using</span> v8::Local;
1423<span class="hljs-keyword">using</span> v8::Object;
1424<span class="hljs-keyword">using</span> v8::String;
1425<span class="hljs-keyword">using</span> v8::Value;
1426
1427<span class="hljs-comment">// Warning! This is not thread-safe, this addon cannot be used for worker</span>
1428<span class="hljs-comment">// threads.</span>
1429Global&#x3C;Function> MyObject::constructor;
1430
1431MyObject::<span class="hljs-built_in">MyObject</span>(<span class="hljs-type">double</span> value) : <span class="hljs-built_in">value_</span>(value) {
1432}
1433
1434MyObject::~<span class="hljs-built_in">MyObject</span>() {
1435}
1436
1437<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">MyObject::Init</span><span class="hljs-params">(Isolate* isolate)</span> </span>{
1438  <span class="hljs-comment">// Prepare constructor template</span>
1439  Local&#x3C;FunctionTemplate> tpl = FunctionTemplate::<span class="hljs-built_in">New</span>(isolate, New);
1440  tpl-><span class="hljs-built_in">SetClassName</span>(String::<span class="hljs-built_in">NewFromUtf8</span>(isolate, <span class="hljs-string">"MyObject"</span>).<span class="hljs-built_in">ToLocalChecked</span>());
1441  tpl-><span class="hljs-built_in">InstanceTemplate</span>()-><span class="hljs-built_in">SetInternalFieldCount</span>(<span class="hljs-number">1</span>);
1442
1443  Local&#x3C;Context> context = isolate-><span class="hljs-built_in">GetCurrentContext</span>();
1444  constructor.<span class="hljs-built_in">Reset</span>(isolate, tpl-><span class="hljs-built_in">GetFunction</span>(context).<span class="hljs-built_in">ToLocalChecked</span>());
1445
1446  <span class="hljs-built_in">AddEnvironmentCleanupHook</span>(isolate, [](<span class="hljs-type">void</span>*) {
1447    constructor.<span class="hljs-built_in">Reset</span>();
1448  }, <span class="hljs-literal">nullptr</span>);
1449}
1450
1451<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">MyObject::New</span><span class="hljs-params">(<span class="hljs-type">const</span> FunctionCallbackInfo&#x3C;Value>&#x26; args)</span> </span>{
1452  Isolate* isolate = args.<span class="hljs-built_in">GetIsolate</span>();
1453  Local&#x3C;Context> context = isolate-><span class="hljs-built_in">GetCurrentContext</span>();
1454
1455  <span class="hljs-keyword">if</span> (args.<span class="hljs-built_in">IsConstructCall</span>()) {
1456    <span class="hljs-comment">// Invoked as constructor: `new MyObject(...)`</span>
1457    <span class="hljs-type">double</span> value = args[<span class="hljs-number">0</span>]-><span class="hljs-built_in">IsUndefined</span>() ?
1458        <span class="hljs-number">0</span> : args[<span class="hljs-number">0</span>]-><span class="hljs-built_in">NumberValue</span>(context).<span class="hljs-built_in">FromMaybe</span>(<span class="hljs-number">0</span>);
1459    MyObject* obj = <span class="hljs-keyword">new</span> <span class="hljs-built_in">MyObject</span>(value);
1460    obj-><span class="hljs-built_in">Wrap</span>(args.<span class="hljs-built_in">This</span>());
1461    args.<span class="hljs-built_in">GetReturnValue</span>().<span class="hljs-built_in">Set</span>(args.<span class="hljs-built_in">This</span>());
1462  } <span class="hljs-keyword">else</span> {
1463    <span class="hljs-comment">// Invoked as plain function `MyObject(...)`, turn into construct call.</span>
1464    <span class="hljs-type">const</span> <span class="hljs-type">int</span> argc = <span class="hljs-number">1</span>;
1465    Local&#x3C;Value> argv[argc] = { args[<span class="hljs-number">0</span>] };
1466    Local&#x3C;Function> cons = Local&#x3C;Function>::<span class="hljs-built_in">New</span>(isolate, constructor);
1467    Local&#x3C;Object> instance =
1468        cons-><span class="hljs-built_in">NewInstance</span>(context, argc, argv).<span class="hljs-built_in">ToLocalChecked</span>();
1469    args.<span class="hljs-built_in">GetReturnValue</span>().<span class="hljs-built_in">Set</span>(instance);
1470  }
1471}
1472
1473<span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">MyObject::NewInstance</span><span class="hljs-params">(<span class="hljs-type">const</span> FunctionCallbackInfo&#x3C;Value>&#x26; args)</span> </span>{
1474  Isolate* isolate = args.<span class="hljs-built_in">GetIsolate</span>();
1475
1476  <span class="hljs-type">const</span> <span class="hljs-type">unsigned</span> argc = <span class="hljs-number">1</span>;
1477  Local&#x3C;Value> argv[argc] = { args[<span class="hljs-number">0</span>] };
1478  Local&#x3C;Function> cons = Local&#x3C;Function>::<span class="hljs-built_in">New</span>(isolate, constructor);
1479  Local&#x3C;Context> context = isolate-><span class="hljs-built_in">GetCurrentContext</span>();
1480  Local&#x3C;Object> instance =
1481      cons-><span class="hljs-built_in">NewInstance</span>(context, argc, argv).<span class="hljs-built_in">ToLocalChecked</span>();
1482
1483  args.<span class="hljs-built_in">GetReturnValue</span>().<span class="hljs-built_in">Set</span>(instance);
1484}
1485
1486}  <span class="hljs-comment">// namespace demo</span></code> <button class="copy-button">copy</button></pre>
1487<p>Test it with:</p>
1488<pre><code class="language-js"><span class="hljs-comment">// test.js</span>
1489<span class="hljs-keyword">const</span> addon = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./build/Release/addon'</span>);
1490
1491<span class="hljs-keyword">const</span> obj1 = addon.<span class="hljs-title function_">createObject</span>(<span class="hljs-number">10</span>);
1492<span class="hljs-keyword">const</span> obj2 = addon.<span class="hljs-title function_">createObject</span>(<span class="hljs-number">20</span>);
1493<span class="hljs-keyword">const</span> result = addon.<span class="hljs-title function_">add</span>(obj1, obj2);
1494
1495<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(result);
1496<span class="hljs-comment">// Prints: 30</span></code> <button class="copy-button">copy</button></pre></section>
1497        <!-- API END -->
1498      </div>
1499    </div>
1500  </div>
1501</body>
1502</html>
1503