{"id":13417922,"url":"https://github.com/charto/nbind","last_synced_at":"2025-05-14T23:07:41.464Z","repository":{"id":24647812,"uuid":"28057652","full_name":"charto/nbind","owner":"charto","description":":sparkles: Magical headers that make your C++ library accessible from JavaScript :rocket:","archived":false,"fork":false,"pushed_at":"2019-05-04T19:09:03.000Z","size":1101,"stargazers_count":1986,"open_issues_count":65,"forks_count":118,"subscribers_count":49,"default_branch":"master","last_synced_at":"2025-05-14T10:21:19.747Z","etag":null,"topics":["asmjs","c-plus-plus","emscripten","node-addon","nodejs","typescript"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/charto.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-12-15T21:43:17.000Z","updated_at":"2025-04-28T04:22:38.000Z","dependencies_parsed_at":"2022-08-07T11:01:13.603Z","dependency_job_id":null,"html_url":"https://github.com/charto/nbind","commit_stats":null,"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charto%2Fnbind","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charto%2Fnbind/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charto%2Fnbind/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charto%2Fnbind/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/charto","download_url":"https://codeload.github.com/charto/nbind/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254152483,"owners_count":22023435,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asmjs","c-plus-plus","emscripten","node-addon","nodejs","typescript"],"created_at":"2024-07-30T22:00:55.493Z","updated_at":"2025-05-14T23:07:36.456Z","avatar_url":"https://github.com/charto.png","language":"C++","readme":"[Quick start](#quick-start) |\n[Requirements](#requirements) |\n[Features](#features) |\n[User guide](#user-guide) |\n[Contributing](#contributing) |\n[License](#license)\n\n[![nbind flowchart](doc/images/diagram.png)](doc/images/diagram.png)\n\n`nbind` is a set of headers that make your C++11 library accessible from JavaScript.\nWith a single `#include` statement, your C++ compiler generates the necessary bindings\nwithout any additional tools. Your library is then usable as a Node.js addon or,\nif compiled to asm.js with [Emscripten](http://emscripten.org),\ndirectly in web pages without any plugins.\n\n`nbind` works with the [autogypi](https://github.com/charto/autogypi) dependency management tool,\nwhich sets up `node-gyp` to compile your library without needing any configuration\n(other than listing your source code file names).\n\n`nbind` is **MIT licensed** and based on templates and macros inspired by\n[embind](http://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/embind.html).\n\nQuick start\n===========\n\nC++ everywhere in 5 easy steps using Node.js, `nbind` and [autogypi](https://github.com/charto/autogypi):\n\n\u003ctable\u003e\n\u003ctr\u003e\n\t\u003cth\u003eStarting point\u003c/th\u003e\n\t\u003cth\u003eStep 1 - bind\u003c/th\u003e\n\t\u003cth\u003eStep 2 - prepare\u003c/th\u003e\n\u003c/tr\u003e\u003ctr\u003e\n\u003ctd valign=\"top\"\u003eOriginal C++ code \u003ca href=\"https://raw.githubusercontent.com/charto/nbind-example-minimal/master/hello.cc\"\u003e\u003ccode\u003ehello.cc\u003c/code\u003e\u003c/a\u003e:\u003cbr\u003e\n\u003cpre\u003e#include \u0026lt;string\u0026gt;\n#include \u0026lt;iostream\u0026gt;\n\u0026nbsp;\nstruct Greeter {\n  static void sayHello(\n    std::string name\n  ) {\n    std::cout\n      \u0026lt;\u0026lt; \"Hello, \"\n      \u0026lt;\u0026lt; name \u0026lt;\u0026lt; \"!\\n\";\n  }\n};\u003c/pre\u003e\u003c/td\u003e\n\u003ctd valign=\"top\"\u003eList your \u003ca href=\"#classes-and-constructors\"\u003eclasses\u003c/a\u003e and \u003ca href=\"#methods-and-properties\"\u003emethods\u003c/a\u003e:\u003cbr\u003e\n\u003cpre\u003e// Your original code here\n\u0026nbsp;\n// Add these below it:\n\u0026nbsp;\n#include \"nbind/nbind.h\"\n\u0026nbsp;\nNBIND_CLASS(Greeter) {\n  method(sayHello);\n}\u003c/pre\u003e\u003c/td\u003e\n\u003ctd valign=\"top\"\u003e\u003ca href=\"#creating-your-project\"\u003eAdd scripts\u003c/a\u003e to \u003ca href=\"https://raw.githubusercontent.com/charto/nbind-example-minimal/master/package.json\"\u003e\u003ccode\u003epackage.json\u003c/code\u003e\u003c/a\u003e:\u003cbr\u003e\n\u003cpre\u003e{\n  \"scripts\": {\n    \"autogypi\": \"autogypi\",\n    \"node-gyp\": \"node-gyp\",\n    \"emcc-path\": \"emcc-path\",\n    \"copyasm\": \"copyasm\",\n    \"ndts\": \"ndts\"\n  }\n}\u003c/pre\u003e\u003c/td\u003e\n\u003c/tr\u003e\u003ctr\u003e\n\t\u003cth\u003eStep 3 - install\u003c/th\u003e\n\t\u003cth\u003eStep 4 - build\u003c/th\u003e\n\t\u003cth\u003eStep 5 - use!\u003c/th\u003e\n\u003c/tr\u003e\u003ctr\u003e\n\u003ctd valign=\"top\"\u003eRun on the command line:\u003cbr\u003e\n\u003cpre\u003enpm install --save \\\n  nbind autogypi node-gyp\n\u0026nbsp;\nnpm run -- autogypi \\\n  --init-gyp \\\n  -p nbind -s hello.cc\u003c/pre\u003e\u003c/td\u003e\n\u003ctd valign=\"top\"\u003eCompile to native binary:\u003cbr\u003e\n\u003cpre\u003enpm run -- node-gyp \\\n  configure build\u003c/pre\u003e\nOr to Asm.js:\u003cbr\u003e\n\u003cpre\u003enpm run -- node-gyp \\\n  configure build \\\n  --asmjs=1\u003c/pre\u003e\u003c/td\u003e\n\u003ctd valign=\"top\"\u003eCall from Node.js:\u003cbr\u003e\n\u003cpre\u003evar nbind = require('nbind');\nvar lib = nbind.init().lib;\n\u0026nbsp;\nlib.Greeter.sayHello('you');\u003c/pre\u003e\nOr from a web browser (\u003ca href=\"#using-in-web-browsers\"\u003esee below\u003c/a\u003e).\n\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\nThe above is **all** of the required code. Just copy and paste in the mentioned files and prompts or take a shortcut:\n\n```bash\ngit clone https://github.com/charto/nbind-example-minimal.git\ncd nbind-example-minimal\nnpm install \u0026\u0026 npm test\n```\n\nSee it run!\n\n(Note: [nbind-example-universal](https://github.com/charto/nbind-example-universal)\nis a better starting point for development)\n\nRequirements\n============\n\nYou need:\n\n- [Node.js](https://nodejs.org/en/) 0.10.x - 7.x.x (newer may also work).\n- Python 2.7, NOT 3.x (required by `node-gyp`, [see instructions](https://github.com/nodejs/node-gyp#installation)).\n\nAnd one of the following C++ compilers:\n\n- GCC 4.8 or above.\n- Clang 3.6 or above.\n- Emscripten 1.35.0 or above.\n- Visual Studio 2015 ([the Community version](https://www.visualstudio.com/en-us/products/visual-studio-community-vs.aspx) is fine).\n\nFeatures\n========\n\n`nbind` allows you to:\n\n- Use your C++ API from JavaScript without any extra effort.\n  - From **Node.js**, **Electron** and web browsers (using asm.js on **Chrome**, **Firefox** and **Edge**).\n  - On Linux, OS X and Windows.\n  - Without changes to your C++ code. Simply add a separate short description at the end.\n- Distribute both **native** code and an **asm.js** fallback binary.\n- Automatically generate TypeScript `.d.ts` definition files from C++ code for IDE autocompletion and compile-time checks of JavaScript side code.\n\nIn more detail:\n\n- Export multiple C++ classes, even ones not visible from other files.\n- Export C++ methods simply by mentioning their names.\n- Auto-detect argument and return types from C++ declarations.\n- [Automatically convert types](#type-conversion) and data structures between languages.\n- Call C++ methods from JavaScript with type checking.\n- Pass JavaScript callbacks to C++ and call them with any types.\n- Pass instances of compatible classes by value between languages (through the C++ stack).\n\nThe goal is to provide a **stable API** for binding C++ to JavaScript.\nAll internals related to JavaScript engines are hidden away,\nand a single API already supports *extremely* different platforms.\n\nWorks on your platform\n----------------------\n\n\u003ctable\u003e\n\t\u003ctr\u003e\n\t\t\u003cth\u003eTarget\u003c/th\u003e\n\t\t\u003cth colspan=2\u003eDevelopment platform\u003c/th\u003e\n\t\u003c/tr\u003e\u003ctr\u003e\n\t\t\u003cth\u003e\u003c/th\u003e\n\t\t\u003cth\u003eLinux / OS X\u003c/th\u003e\n\t\t\u003cth\u003eWindows\u003c/th\u003e\n\t\u003c/tr\u003e\u003ctr\u003e\n\t\t\u003ctd\u003eNative\u003c/td\u003e\n\t\t\u003ctd\u003e\n\t\t\t\u003ca href=\"http://travis-ci.org/charto/nbind\"\u003e\n\t\t\t\t\u003cimg src=\"https://travis-ci.org/charto/nbind.svg?branch=master\" alt=\"Build status\"\u003e\n\t\t\t\u003c/a\u003e\n\t\t\u003c/td\u003e\n\t\t\u003ctd\u003e\n\t\t\t\u003ca href=\"https://ci.appveyor.com/project/jjrv/nbind/branch/master\"\u003e\n\t\t\t\t\u003cimg src=\"https://ci.appveyor.com/api/projects/status/xu5ooh1m3mircpde/branch/master?svg=true\" alt=\"Build status\"\u003e\n\t\t\t\u003c/a\u003e\n\t\t\u003c/td\u003e\n\t\u003c/tr\u003e\u003ctr\u003e\n\t\t\u003ctd\u003eAsm.js\u003c/td\u003e\n\t\t\u003ctd\u003e\n\t\t\t\u003ca href=\"http://travis-ci.org/charto/nbind-ci-emscripten\"\u003e\n\t\t\t\t\u003cimg src=\"https://travis-ci.org/charto/nbind-ci-emscripten.svg?branch=master\" alt=\"Build status\"\u003e\n\t\t\t\u003c/a\u003e\n\t\t\u003c/td\u003e\n\t\t\u003ctd\u003eTested manually\u003c/td\u003e\n\t\u003c/tr\u003e\n\u003c/table\u003e\n\n[![dependency status](https://david-dm.org/charto/nbind.svg)](https://david-dm.org/charto/nbind)\n[![npm version](https://img.shields.io/npm/v/nbind.svg)](https://www.npmjs.com/package/nbind)\n\nRoadmap\n-------\n\nMore is coming! Work is ongoing to:\n\n- Precompile to a single native library for all versions Node.js and Electron on the same platform\n  - Precompiled addons for different Node.js versions for efficiently calling the library will be provided with nbind\n- Support native Android and iPhone apps.\n\nFuture `0.x.y` versions *should* remain completely backwards-compatible between matching `x` and otherwise with minor changes.\nBreaking changes will be listed in release notes of versions where `y` equals `0`.\n\nContributing\n============\n\nPlease report issues through Github and mention the platform you're targeting\n(Node.js, asm.js, Electron or something else). Pull requests are very welcome.\n\nWarning: rebase is used within develop and feature branches (but not master).\n\nWhen developing new features, writing tests first works best.\nIf possible, please try to get them working on both Node.js and asm.js.\nOtherwise your pull request will get merged to Master only after\nmaintainer(s) have fixed the other platform.\n\nInstalling Emscripten to develop for asm.js can be tricky. It will require\nPython 2.7 and setting paths correctly, please refer to\n[Emscripten documentation](https://kripken.github.io/emscripten-site/docs/getting_started/downloads.html).\nThe `bin/emcc` script in this package is just a wrapper,\nthe actual `emcc` compiler binary should be in your path.\n\nYou can rebuild the asm.js library and run tests as follows:\n\n```bash\nnpm run clean-asm \u0026\u0026 npm run prepublish \u0026\u0026 npm run test-asm\n```\n\nUser guide\n==========\n\n- [Installing the examples](#installing-the-examples)\n- [Creating your project](#creating-your-project)\n- [Configuration](#configuration)\n- [Calling from Node.js](#calling-from-nodejs)\n- [Using nbind headers](#using-nbind-headers)\n- [Functions](#functions)\n- [Classes and constructors](#classes-and-constructors)\n- [Inheritance](#inheritance) \u003csup\u003enew in 0.3.5\u003c/sup\u003e\n- [Methods and properties](#methods-and-properties)\n- [Overloaded functions](#overloaded-functions) \u003csup\u003enew in 0.3.2\u003c/sup\u003e\n- [Getters and setters](#getters-and-setters)\n- [Passing data structures](#passing-data-structures)\n- [Callbacks](#callbacks)\n- [Using objects](#using-objects)\n- [Type conversion](#type-conversion) \u003csup\u003eupdated in 0.3.2\u003c/sup\u003e\n- [Buffers](#buffers) \u003csup\u003enew in 0.3.1\u003c/sup\u003e\n- [64-bit integers](#64-bit-integers) \u003csup\u003enew in 0.3.0\u003c/sup\u003e\n- [Error handling](#error-handling)\n- [Publishing on npm](#publishing-on-npm)\n- [Shipping an asm.js fallback](#shipping-an-asmjs-fallback)\n- [Using in web browsers](#using-in-web-browsers) \u003csup\u003eupdated in 0.3.0\u003c/sup\u003e\n- [Using with TypeScript](#using-with-typescript) \u003csup\u003eupdated in 0.3.5\u003c/sup\u003e\n- [Binding plain C](#binding-plain-c)\n- [Binding external libraries](#binding-external-libraries)\n- [Debugging](#debugging)\n- [Alternatives](#alternatives)\n\nInstalling the examples\n-----------------------\n\n`nbind` examples shown in this user guide are also available to download\nfor easier testing as follows:\n\nExtract [this zip package](https://github.com/charto/nbind-examples/archive/master.zip) or run:\n\n```bash\ngit clone https://github.com/charto/nbind-examples.git\n```\n\nEnter the examples directory and install:\n\n```bash\ncd nbind-examples\nnpm install\n```\n\nCreating your project\n---------------------\n\nOnce you have all [requirements](#requirements) installed, run:\n\n```bash\nnpm init\nnpm install --save nbind autogypi node-gyp\n```\n\n`nbind`, `autogypi` and `node-gyp` are all needed to compile\na native Node.js addon from source when installing it.\nIf you only distribute an asm.js version, you can use\n`--save-dev` instead of `--save` because users won't need to compile it.\n\nNext, to run commands without installing them globally, it's practical\nto add them in the `scripts` section of your `package.json` that `npm init`\njust generated. Let's add an install script as well:\n\n```json\n  \"scripts\": {\n    \"autogypi\": \"autogypi\",\n    \"node-gyp\": \"node-gyp\",\n    \"emcc-path\": \"emcc-path\",\n    \"copyasm\": \"copyasm\",\n\n    \"install\": \"autogypi \u0026\u0026 node-gyp configure build\"\n  }\n```\n\n`emcc-path` is needed internally by `nbind` when compiling for asm.js.\nIt fixes some command line options that `node-gypi` generates on OS X\nand the Emscripten compiler doesn't like.\nYou can leave it out if only compiling native addons.\n\nThe `install` script runs when anyone installs your package.\nIt calls `autogypi` and then uses `node-gyp` to compile a native addon.\n\n`autogypi` uses npm package information to set correct include paths\nfor C/C++ compilers. It's needed when distributing addons on npm\nso the compiler can find header files from the `nbind` and `nan` packages\ninstalled on the user's machine. Initialize it like this:\n\n```bash\nnpm run -- autogypi --init-gyp -p nbind -s hello.cc\n```\n\nReplace `hello.cc` with the name of your C++ source file.\nYou can add multiple `-s` options, one for each source file.\n\nThe `-p nbind` means the C++ code uses `nbind`. Multiple `-p`\noptions can be added to add any other packages compatible with `autogypi`.\n\nThe `--init-gyp` command generates files `binding.gyp` and `autogypi.json`\nthat you should distribute with your package, so that `autogypi` and `node-gyp`\nwill know what to do when the `install` script runs.\n\nNow you're ready to start writing code and compiling.\n\nConfiguration\n-------------\n\nRefer to [autogypi documentation](https://github.com/charto/autogypi#readme)\nto set up dependencies of your package, and how other packages\nshould include it if it's a library usable directly from C++.\n\n`--asmjs=1` is the only existing configuration option for `nbind` itself.\nYou pass it to `node-gyp` by calling it like `node-gyp configure build --asmjs=1`.\nIt compiles your package using Emscripten instead of your default C++ compiler\nand produces asm.js output.\n\nCalling from Node.js\n--------------------\n\nFirst `nbind` needs to be initialized by calling `nbind.init` which takes\nthe following optional arguments:\n\n- Base path under which to look for compiled binaries.\n  Default is `process.cwd()` and `__dirname` is a good alternative.\n- Binary code exports object. Any classes from C++ API exported using `nbind`\n  will be added as members. Default is an empty object.\n  Any existing options will be seen by asm.js code and can be used to\n  [configure Emscripten output](https://kripken.github.io/emscripten-site/docs/api_reference/module.html).\n  Must follow base path (which may be set to `null` or `undefined`).\n- Node-style callback with 2 parameters:\n  - Error if present, otherwise `null`.\n  - Binary code exports object containing C++ classes.\n\n`nbind` can be initialized synchronously on Node.js and asynchronously on\nbrowsers and Node.js. Purely synchronous is easier but not as future-proof:\n\n```JavaScript\nvar nbind = require('nbind');\nvar lib = nbind.init().lib;\n\n// Use the library.\n```\n\nUsing a callback also supports asynchronous initialization:\n\n```JavaScript\nvar nbind = require('nbind');\n\nnbind.init(function(err, binding) {\n  var lib = binding.lib;\n\n  // Use the library.\n});\n```\n\nThe callback passed to init currently gets called synchronously in Node.js\nand asynchronously in browsers. To avoid releasing\n[zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony)\nyou can for example wrap the call in a\n[bluebird](http://bluebirdjs.com/docs/api/promise.promisify.html) promise:\n\n```JavaScript\nvar bluebird = require('bluebird');\nvar nbind = require('nbind');\n\nbluebird.promisify(nbind.init)().then(function(binding) {\n  var lib = binding.lib;\n\n  // Use the library.\n});\n```\n\nUsing nbind headers\n-------------------\n\nThere are two possible files to include:\n\n- `nbind/api.h` for using types from the `nbind` namespace such as JavaScript callbacks inside your C++ code.\n  - `#include` **before** your own class definitions.\n  - Causes your code to depend on `nbind`.\n- `nbind/nbind.h` for exposing your C++ API to JavaScript.\n  - `#include` **after** your own class definitions to avoid accidentally invoking its macros.\n  - The header automatically hides itself if not targeting Node.js or asm.js.\n  - Safe to use in any projects.\n\nUse `#include \"nbind/nbind.h\"` at the end of your source file with only the bindings after it.\nThe header defines macros with names like `construct` and `method` that may otherwise break\nyour code or conflict with other headers.\n\nIt's OK to include `nbind/nbind.h` also when not targeting any JavaScript environment.\n`node-gyp` defines a `BUILDING_NODE_EXTENSION` macro and Emscripten defines an `EMSCRIPTEN` macro\nso when those are undefined, the include file does nothing.\n\nUse `#include \"nbind/api.h\"` in your header files to use types in the nbind namespace\nif you need to [report errors](#error-handling) without throwing exceptions,\nor want to pass around [callbacks](#callbacks) or [objects](#using-objects).\n\nYou can use an `#ifdef NBIND_CLASS` guard to skip your `nbind` export definitions when the headers weren't loaded.\n\nExample that uses an `nbind` callback in C++ code:\n\n**[`1-headers.cc`](https://raw.githubusercontent.com/charto/nbind-examples/master/1-headers.cc)**\n\n```C++\n#include \u003cstring\u003e\n#include \u003ciostream\u003e\n\n// For nbind::cbFunction type.\n#include \"nbind/api.h\"\n\nclass HeaderExample {\n\npublic:\n\n  static void callJS(nbind::cbFunction \u0026callback) {\n    std::cout \u003c\u003c \"JS says: \" \u003c\u003c callback.call\u003cstd::string\u003e(1, 2, 3);\n  }\n\n};\n\n// For NBIND_CLASS() and method() macros.\n#include \"nbind/nbind.h\"\n\n#ifdef NBIND_CLASS\n\nNBIND_CLASS(HeaderExample) {\n  method(callJS);\n}\n\n#endif\n```\n\nExample used from JavaScript:\n\n**[`1-headers.js`](https://raw.githubusercontent.com/charto/nbind-examples/master/1-headers.js)**\n\n```JavaScript\nvar nbind = require('nbind');\n\nvar lib = nbind.init().lib;\n\nlib.HeaderExample.callJS(function(a, b, c) {\n  return('sum = ' + (a + b + c) + '\\n');\n});\n```\n\nRun the example with `node 1-headers.js` after [installing](#installing-the-examples). It prints:\n\n```\nJS says: sum = 6\n```\n\nFunctions\n---------\n\nFunctions not belonging to any class are exported inside an `NBIND_GLOBAL`\nblock with a macro call `function(functionName);` which takes the name of\nthe function as an argument (without any quotation marks).\nThe C++ function gets exported to JavaScript with the same name,\nor it can be renamed by adding a second argument (with quotation marks):\n`function(cppFunctionName, \"jsExportedName\");`\n\nIf the C++ function is overloaded, `multifunction` macro must be used\ninstead. See [overloaded functions](#overloaded-functions).\n\nNote: you cannot put several `function(...);` calls on the same line!\nOtherwise you'll get an error about redefining a symbol.\n\nExample:\n\n**[`6-functions.cc`](https://raw.githubusercontent.com/charto/nbind-examples/master/6-functions.cc)**\n\n```C++\n#include \u003ciostream\u003e\n\nvoid sayHello(std::string name) {\n  std::cout \u003c\u003c \"Hello, \" \u003c\u003c name \u003c\u003c \"!\\n\";\n}\n\n#include \"nbind/nbind.h\"\n\nNBIND_GLOBAL() {\n  function(sayHello);\n}\n```\n\nExample used from JavaScript:\n\n**[`6-functions.js`](https://raw.githubusercontent.com/charto/nbind-examples/master/6-functions.js)**\n\n```JavaScript\nvar nbind = require('nbind');\nvar lib = nbind.init().lib;\n\nlib.sayHello('you');\n```\n\nClasses and constructors\n------------------------\n\nThe `NBIND_CLASS(className)` macro takes the name of your C++ class as an argument\n(without any quotation marks), and exports it to JavaScript using the same name.\nIt's followed by a curly brace enclosed block of method exports,\nas if it was a function definition.\n\nThe class can be renamed on the JavaScript side by passing a string as a\nsecond argument. This is especially useful for binding a template class\nspecialization with a more reasonable name: `NBIND_CLASS(Data\u003cint\u003e, \"IntData\")`\n\nConstructors are exported with a macro call `construct\u003ctypes...\u003e();` where `types` is a comma-separated list of arguments to the constructor, such as `int, int`. Calling `construct` multiple times allows overloading it, but **each overload must have a different number of arguments**.\n\nConstructor arguments are the only types that `nbind` cannot detect automatically.\n\nExample with different constructor argument counts and types:\n\n**[`2-classes.cc`](https://raw.githubusercontent.com/charto/nbind-examples/master/2-classes.cc)**\n\n```C++\n#include \u003ciostream\u003e\n\nclass ClassExample {\n\npublic:\n\n  ClassExample() {\n    std::cout \u003c\u003c \"No arguments\\n\";\n  }\n  ClassExample(int a, int b) {\n    std::cout \u003c\u003c \"Ints: \" \u003c\u003c a \u003c\u003c \" \" \u003c\u003c b \u003c\u003c \"\\n\";\n  }\n  ClassExample(const char *msg) {\n    std::cout \u003c\u003c \"String: \" \u003c\u003c msg \u003c\u003c \"\\n\";\n  }\n\n};\n\n#include \"nbind/nbind.h\"\n\nNBIND_CLASS(ClassExample) {\n  construct\u003c\u003e();\n  construct\u003cint, int\u003e();\n  construct\u003cconst char *\u003e();\n}\n```\n\nExample used from JavaScript:\n\n**[`2-classes.js`](https://raw.githubusercontent.com/charto/nbind-examples/master/2-classes.js)**\n\n```JavaScript\nvar nbind = require('nbind');\n\nvar lib = nbind.init().lib;\n\nvar a = new lib.ClassExample();\nvar b = new lib.ClassExample(42, 54);\nvar c = new lib.ClassExample(\"Don't panic\");\n```\n\nRun the example with `node 2-classes.js` after [installing](#installing-the-examples). It prints:\n\n```\nNo arguments\nInts: 42 54\nString: Don't panic\n```\n\nInheritance\n-----------\n\nWhen a C++ class inherits another, the `inherit` macro can be used to allow calling parent\nclass methods on the child class, or passing child class instances to C++ methods expecting\nparent class instances.\n\nInternally JavaScript only has prototype-based single inheritance while C++ supports\nmultiple inheritance. To simulate it, nbind will use one parent class as the child class\nprototype, and copy the contents of the other parents to the prototype. This has otherwise\nthe same effect, except the JavaScript `instanceof` operator will return `true` for only\none of the parent classes.\n\nExample:\n\n```JavaScript\nNBIND_CLASS(Child) {\n    inherit(FirstParent);\n    inherit(SecondParent);\n}\n```\n\nMethods and properties\n----------------------\n\nMethods are exported inside an `NBIND_CLASS` block with a macro call `method(methodName);`\nwhich takes the name of the method as an argument (without any quotation marks).\nThe C++ method gets exported to JavaScript with the same name.\n\nIf the C++ method is overloaded, `multimethod` macro must be used instead.\nSee [overloaded functions](#overloaded-functions).\n\nProperties should be accessed through [getter and setter functions](#getters-and-setters).\n\nData types of method arguments and its return value are detected automatically\nso you don't have to specify them. Note the [supported data types](#type-conversion)\nbecause using other types may cause compiler errors that are difficult to understand.\n\nIf the method is `static`, it becomes a property of the JavaScript constructor function\nand can be accessed like `className.methodName()`. Otherwise it becomes a property of\nthe prototype and can be accessed like `obj = new className(); obj.methodName();`\n\nExample with a method that counts a cumulative checksum of ASCII character values in strings,\nand a static method that processes an entire array of strings:\n\n**[`3-methods.cc`](https://raw.githubusercontent.com/charto/nbind-examples/master/3-methods.cc)**\n\n```C++\n#include \u003cstring\u003e\n#include \u003cvector\u003e\n\nclass MethodExample {\n\npublic:\n\n  unsigned int add(std::string part) {\n    for(char \u0026c : part) sum += c;\n\n    return(sum);\n  }\n\n  static std::vector\u003cunsigned int\u003e check(std::vector\u003cstd::string\u003e list) {\n    std::vector\u003cunsigned int\u003e result;\n    MethodExample example;\n\n    for(auto \u0026\u0026part : list) result.push_back(example.add(part));\n\n    return(result);\n  }\n\n  unsigned int sum = 0;\n\n};\n\n#include \"nbind/nbind.h\"\n\nNBIND_CLASS(MethodExample) {\n  construct\u003c\u003e();\n\n  method(add);\n  method(check);\n}\n```\n\nExample used from JavaScript, first calling a method in a loop from JS\nand then a static method returning an array:\n\n**[`3-methods.js`](https://raw.githubusercontent.com/charto/nbind-examples/master/3-methods.js)**\n\n```JavaScript\nvar nbind = require('nbind');\n\nvar lib = nbind.init().lib;\n\nvar parts = ['foo', 'bar', 'quux'];\n\nvar checker = new lib.MethodExample();\n\nconsole.log(parts.map(function(part) {\n  return(checker.add(part));\n}));\n\nconsole.log(lib.MethodExample.check(parts));\n```\n\nRun the example with `node 3-methods.js` after [installing](#installing-the-examples). It prints:\n\n```\n[ 324, 633, 1100 ]\n[ 324, 633, 1100 ]\n```\n\nThe example serves to illustrate passing data.\nIn practice, such simple calculations are faster to do in JavaScript\nrather than calling across languages because copying data is quite expensive.\n\nOverloaded functions\n--------------------\n\nThe `function()` and `method()` macroes cannot distinguish between several\noverloaded versions of the same function or method, causing an error.\nIn this case the `multifunction()` and `multimethod()` macroes must be used.\n\nTheir second parameter is a list of argument types wrapped in an\n`args()` macro to select a single overloaded version.\n\nFor example consider an overloaded method:\n\n```C++\nvoid test(unsigned int x) const;\nvoid test(unsigned int x, unsigned int y) const;\n```\n\nIn bindings, one of the versions needs to be explicitly selected.\nThe second of the two would be referenced like:\n\n```C++\nmultimethod(test, args(unsigned int, unsigned int));\n```\n\nAs always, the return type and method constness are autodetected.\n\nFor calling from JavaScript, additionally each overload needs to have a distinct name.\nFor renaming an overload JavaScript will see, the binding code is like:\n\n```C++\nmultimethod(test, args(unsigned int, unsigned int), \"test2\");\n```\n\nYou can then write a JavaScript wrapper to inspect arguments and select which\noverload to call. The reason for this is, that `nbind` binds a JavaScript property to\na single C++ function pointer, which wraps one overloaded version of the function\nwith type conversion code.\n\nOtherwise, it would need to generate a new C++ function that also checks the arguments.\nThis would result in a larger native binary without any speed advantage.\n\nGetters and setters\n-------------------\n\nProperty getters are exported inside an `NBIND_CLASS` block with a macro call\n`getter(getterName)` with the name of the getter method as an argument.\n`nbind` automatically strips a `get`/`Get`/`get_`/`Get_` prefix and\nconverts the next letter to lowercase, so for example `getX` and `get_x`\nboth would become getters of `x` to be accessed like `obj.x`\n\nProperty setters are exported together with getters using a macro call\n`getset(getterName, setterName)` which works much like `getter(getterName)` above.\nBoth `getterName` and `setterName` are mangled individually so\nyou can pair `getX` with `set_x` if you like.\nFrom JavaScript, `++obj.x` would then call both of them to read and change the property.\n\nExample class and property with a getter and setter:\n\n**[`4-getset.cc`](https://raw.githubusercontent.com/charto/nbind-examples/master/4-getset.cc)**\n\n```C++\nclass GetSetExample {\n\npublic:\n\n  void setValue(int value) { this-\u003evalue = value; }\n  int getValue() { return(value); }\n\nprivate:\n\n  int value = 42;\n\n};\n\n#include \"nbind/nbind.h\"\n\nNBIND_CLASS(GetSetExample) {\n  construct\u003c\u003e();\n\n  getset(getValue, setValue);\n}\n```\n\nExample used from JavaScript:\n\n**[`4-getset.js`](https://raw.githubusercontent.com/charto/nbind-examples/master/4-getset.js)**\n\n```JavaScript\nvar nbind = require('nbind');\n\nvar lib = nbind.init().lib;\n\nvar obj = new lib.GetSetExample();\n\nconsole.log(obj.value++); // 42\nconsole.log(obj.value++); // 43\n```\n\nRun the example with `node 4-getset.js` after [installing](#installing-the-examples).\n\nPassing data structures\n-----------------------\n\n`nbind` supports automatically converting between JavaScript arrays and C++\n`std::vector` or `std::array` types. Just use them as arguments or return values\nin C++ methods.\n\nNote that data structures don't use the same memory layout in both languages,\nso the data always gets copied which takes more time for more data.\nFor example the strings in an array of strings also get copied,\none character at a time. In asm.js data is copied twice, first to a temporary\nspace using a common format both languages can read and write.\n\nCallbacks\n---------\n\nCallbacks can be passed to C++ methods by simply adding an argument of type\n`nbind::cbFunction \u0026` to their declaration.\n\nThey can be called with any number of any supported types without having to declare in any way what they accept.\nThe JavaScript code will receive the parameters as JavaScript variables to do with them as it pleases.\n\nA callback argument `arg` can be called like `arg(\"foobar\", 42);` in which case the return value is ignored.\nIf the return value is needed, the callback must be called like `arg.call\u003ctype\u003e(\"foobar\", 42);`\nwhere type is the desired C++ type that the return value should be converted to.\nThis is because the C++ compiler cannot otherwise know what the callback might return.\n\nWarning: while callbacks are currently passed by reference,\nthey're freed after the called C++ function returns!\nThat's intended for synchronous functions like `Array.map`\nwhich calls a callback zero or more times and then returns.\nFor asynchronous functions like `setTimeout` which calls the callback after it has returned,\nyou need to copy the argument to a new `nbind::cbFunction` and store it somewhere.\n\nUsing objects\n-------------\n\nC++ objects can be passed to and from JavaScript using different\nparameter and return types in C++ code:\n\n- *by reference* using pointers or references (optionally `const`)\n- *by value*\n\nNote: currently passing objects by pointer on Node.js requires the class\nto have a \"copy constructor\" initializing itself from a pointer.\nThis will probably be fixed later.\n\nReturned pointers and references can be `const`, in which case calling their\nnon-const methods or passing them as non-const parameters will throw an error.\nThis prevents causing undefined behaviour corresponding to C++ code that\nwouldn't even compile.\n\nUsing pointers and references is particularly:\n\n- **dangerous** because the pointer may become invalid\n  without JavaScript noticing it.\n- **annoying** in asm.js because browsers give no access to the garbage collector,\n  so memory may leak when pointers become garbage without C++ noticing it.\n  Smart pointers are not supported until a workaround for this is implemented.\n\nPassing data by value using *value objects* solves both issues.\nThey're based on a `toJS` function on the C++ side\nand a `fromJS` function on the JavaScript side.\nBoth receive a callback as an argument, and calling it with any parameters\ncalls the constructor of the equivalent type in the other language.\n\nThe callback on the C++ side is of type `nbind::cbOutput`.\nValue objects are passed through the C++ stack to and from the exported function.\n`nbind` uses C++11 move semantics to avoid creating some additional copies on the way.\n\nThe equivalent JavaScript constructor must be registered on the JavaScript side\nby calling `binding.bind('CppClassName', JSClassName)`\nso that `nbind` knows which types to translate between each other.\n\nExample with a class `Coord` used as a value object, and a class\n`ObjectExample` which uses objects passed by values and references:\n\n**[`5-objects.cc`](https://raw.githubusercontent.com/charto/nbind-examples/master/5-objects.cc)**\n\n```C++\n#include \u003ciostream\u003e\n\n#include \"nbind/api.h\"\n\nclass Coord {\n\npublic:\n\n  Coord(signed int x = 0, signed int y = 0) : x(x), y(y) {}\n  explicit Coord(const Coord *other) : x(other-\u003ex), y(other-\u003ey) {}\n\n  void toJS(nbind::cbOutput output) {\n    output(x, y);\n  }\n\n  signed int getX() { std::cout \u003c\u003c \"Get X\\n\"; return(x); }\n  signed int getY() { std::cout \u003c\u003c \"Get Y\\n\"; return(y); }\n\n  void setX(signed int x) { this-\u003ex = x; }\n  void setY(signed int y) { this-\u003ey = y; }\n\n  signed int x, y;\n\n};\n\nclass ObjectExample {\n\npublic:\n\n  static void showByValue(Coord coord) {\n    std::cout \u003c\u003c \"C++ value \" \u003c\u003c coord.x \u003c\u003c \", \" \u003c\u003c coord.y \u003c\u003c \"\\n\";\n  }\n\n  static void showByRef(Coord *coord) {\n    std::cout \u003c\u003c \"C++ ref \" \u003c\u003c coord-\u003ex \u003c\u003c \", \" \u003c\u003c coord-\u003ey \u003c\u003c \"\\n\";\n  }\n\n  static Coord getValue() {\n    return(Coord(12, 34));\n  }\n\n  static Coord *getRef() {\n    static Coord coord(56, 78);\n    return(\u0026coord);\n  }\n\n};\n\n#include \"nbind/nbind.h\"\n\nNBIND_CLASS(Coord) {\n  construct\u003c\u003e();\n  construct\u003cconst Coord *\u003e();\n  construct\u003csigned int, signed int\u003e();\n\n  getset(getX, setX);\n  getset(getY, setY);\n}\n\nNBIND_CLASS(ObjectExample) {\n  method(showByValue);\n  method(showByRef);\n  method(getValue);\n  method(getRef);\n}\n```\n\nExample used from JavaScript:\n\n**[`5-objects.js`](https://raw.githubusercontent.com/charto/nbind-examples/master/5-objects.js)**\n\n```JavaScript\nvar nbind = require('nbind');\n\nvar binding = nbind.init();\nvar lib = binding.lib;\n\nfunction Coord(x, y) {\n  this.x = x;\n  this.y = y;\n}\n\nCoord.prototype.fromJS = function(output) {\n  output(this.x, this.y);\n}\n\nCoord.prototype.show = function() {\n  console.log('JS value ' + this.x + ', ' + this.y);\n}\n\nbinding.bind('Coord', Coord);\n\nvar value1 = new Coord(123, 456);\nvar value2 = lib.ObjectExample.getValue();\nvar ref = lib.ObjectExample.getRef();\n\nlib.ObjectExample.showByValue(value1);\nlib.ObjectExample.showByValue(value2);\nvalue1.show();\nvalue2.show();\n\nlib.ObjectExample.showByRef(ref);\nconsole.log('JS ref ' + ref.x + ', ' + ref.y);\n```\n\nRun the example with `node 5-objects.js` after [installing](#installing-the-examples). It prints:\n\n```\nC++ value 123, 456\nC++ value 12, 34\nJS value 123, 456\nJS value 12, 34\nC++ ref 56, 78\nGet X\nGet Y\nJS ref 56, 78\n```\n\nType conversion\n---------------\n\nParameters and return values of function calls between languages\nare automatically converted between equivalent types:\n\n| JavaScript | C++                                         |\n| ---------- | ------------------------------------------- |\n| number     | (`un`)`signed char`, `short`, `int`, `long` |\n| number     | `float`, `double`                           |\n| number or [bignum](#64-bit-integers) | (`un`)`signed long`, `long long` |\n| boolean    | `bool`                                      |\n| string     | `const` (`unsigned`) `char *`               |\n| string     | `std::string`                               |\n| Array      | `std::vector\u003ctype\u003e`                         |\n| Array      | `std::array\u003ctype, size\u003e`                    |\n| Function   | `nbind::cbFunction`\u003cbr\u003e(only as a parameter)\u003cbr\u003eSee [Callbacks](#callbacks) |\n| nbind-wrapped pointer | Pointer or reference to an\u003cbr\u003einstance of any bound class\u003cbr\u003eSee [Using objects](#using-objects) |\n| Instance of any prototype\u003cbr\u003e(with a fromJS method) | Instance of any bound class\u003cbr\u003e(with a toJS method)\u003cbr\u003eSee [Using objects](#using-objects) |\n| ArrayBuffer(View), Int*Array\u003cbr\u003eor Buffer | `nbind::Buffer` struct\u003cbr\u003e(data pointer and length)\u003cbr\u003eSee [Buffers](#buffers) |\n\nType conversion is customizable by passing policies as additional arguments\nto `construct`, `function` or `method` inside an `NBIND_CLASS` or `NBIND_GLOBAL` block.\nCurrently supported policies are:\n\n- `nbind::Nullable()` allows passing `null` as an argument when a C++ class instance is expected.\n  The C++ function will then receive a `nullptr`.\n- `nbind::Strict()` enables stricter type checking.\n  Normally anything in JavaScript can be converted to `number`, `string` or `boolean` when expected by a C++ function.\n  This policy requires passing the exact JavaScript type instead.\n\nType conversion policies are listed after the method or function names, for example:\n\n```C++\nNBIND_CLASS(Reference) {\n    method(reticulateSplines, \"reticulate\", nbind::Nullable());\n    method(printString, nbind::Strict());\n}\n```\n\nBuffers\n-------\n\nTransferring large chunks of data between languages is fastest using typed arrays or Node.js buffers in JavaScript.\nBoth are accessible from C++ as plain blocks of memory if passed in through the `nbind::Buffer` data type which has the methods:\n\n- `data()` returns an `unsigned char *` pointing to a block of memory also seen by JavaScript.\n- `length()` returns the length of the block in bytes.\n- `commit()` copies data from C++ back to JavaScript (only needed with Emscripten).\n\nThis is especially useful for passing `canvas.getContext('2d').getImageData(...).data` to C++\nand drawing to an on-screen bitmap when targeting Emscripten or Electron.\n\nExample:\n\n```C++\n#include \"nbind/api.h\"\n\nvoid range(nbind::Buffer buf) {\n  size_t length = buf.length();\n  unsigned char *data = buf.data();\n\n  if(!data || !length) return;\n\n  for(size_t pos = 0; pos \u003c length; ++pos) {\n    data[pos] = pos;\n  }\n\n  buf.commit();\n}\n\n#include \"nbind/nbind.h\"\n\nNBIND_GLOBAL() {\n  function(range);\n}\n```\n\nExample used from JavaScript:\n\n```JavaScript\nvar nbind = require('nbind');\nvar lib = nbind.init().lib;\n\nvar data = new Uint8Array(16);\nlib.range(data);\n\nconsole.log(data.join(' '));\n```\n\nIt prints:\n\n```\n0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n```\n\n64-bit integers\n---------------\n\nNormally C++ 64-bit integer types are first converted to `double` and then to JavaScript number\nwhich can only hold 53 bits of precision, but it's possible to preserve all bits by using a bignum class.\nIt should have a constructor taking the following arguments:\n\n- Integer containing 32 bits from the least important half.\n- Integer containing 32 bits from the most important half.\n- Boolean, true if the number is negative.\n\nIt should also have a `fromJS` function which takes a callback,\nand calls it with those same arguments to pass the data back to C++ when needed.\n\nAn example implementation also capable of printing 64-bit numbers to strings\nin bases 2, 4, 10 and 16 is [included](https://raw.githubusercontent.com/charto/nbind/master/src/int64.ts).\n\nError handling\n--------------\n\nYou can use the `NBIND_ERR(\"message here\");` macro to report an error before returning from C++\n(`#include \"nbind/api.h\"` first). It will be thrown as an error on the JavaScript side\n(C++ environments like Emscripten may not support throwing exceptions, but the JavaScript side will).\n\nPublishing on npm\n-----------------\n\nMake sure your `package.json` file has at least the required `emcc-path`\nand `install` scripts:\n\n```json\n  \"scripts\": {\n    \"emcc-path\": \"emcc-path\",\n\n    \"install\": \"autogypi \u0026\u0026 node-gyp configure build\"\n  }\n```\n\nThe `dependencies` section should have at least:\n\n```json\n  \"dependencies\": {\n    \"autogypi\": \"^0.2.2\",\n\t\"nbind\": \"^0.2.1\",\n    \"node-gyp\": \"^3.3.1\"\n  }\n```\n\nYour package should also include `binding.gyp` and `autogypi.json` files.\n\nShipping an asm.js fallback\n---------------------------\n\n[nbind-example-universal](https://github.com/charto/nbind-example-universal)\nis a good minimal example of compiling a native Node.js addon if possible,\nand otherwise using a pre-compiled asm.js version.\n\nIt has two temporary build directories `build/native` and `build/asmjs`,\nfor compiling both versions. `nbind` provides a binary `copyasm`\nthat can then be used to copy the compiled asm.js library\ninto a nicer location for publishing inside the final npm package.\n\nNote that the native version should be compiled in the `install` script\nso it runs for all users of the package, and the asm.js version should be\ncompiled in the `prepublish` script so it gets packaged in npm for usage\nwithout the Emscripten compiler. See the\n[example `package.json` file](https://github.com/charto/nbind-example-universal/blob/master/package.json).\n\nUsing in web browsers\n---------------------\n\n[nbind-example-universal](https://github.com/charto/nbind-example-universal)\nis a good minimal example also of calling compiled asm.js code from inside\nweb browsers. The simplest way to get `nbind` working is to add\nthese scripts in your HTML code as seen in the\n[example `index.html`](https://github.com/charto/nbind-example-universal/blob/master/public/index.html):\n\n```html\n\u003cscript src=\"nbind.js\"\u003e\u003c/script\u003e\n\n\u003cscript\u003e\n  nbind.init(function(err, binding) {\n    var lib = binding.lib;\n\n    // Use the library.\n  });\n\u003c/script\u003e\n```\n\nMake sure to fix the path to `nbind.js` on the first line if necessary.\n\nUsing with TypeScript\n---------------------\n\n`nbind` has a fully typed API for interacting with C++ code and it can also\nautomatically generate `.d.ts` files for your C++ classes and functions.\nThis gives you effortless bindings with compile time type checking for calls\nfrom JavaScript to Node.js addons and asm.js modules.\n\nAll you have to do is compile your C++ code and run the included `ndts` tool\nto create the type definitions:\n\n```bash\nnpm run -- node-gyp configure build\nnpm run -s -- ndts . \u003e lib-types.d.ts\n```\n\nWhen run in this way, the first argument of `ndts` is a path from the package\nroot to the `binding.gyp` file. Typically the file is in the root so the\ncorrect path is `.`\n\nNow you can load the C++ code from TypeScript in three different ways. First\nimport `nbind` (which also loads the C++ code) and types generated by `ndts`:\n\n```TypeScript\nimport * as nbind from 'nbind';\nimport * as LibTypes from './lib-types';\n```\n\nThen choose your favorite way to initialize it:\n\nPurely synchronous:\n\n```TypeScript\nconst lib = nbind.init\u003ctypeof LibTypes\u003e().lib;\n\n// Use the library.\n```\n\nAsynchronous-aware:\n\n```TypeScript\nnbind.init((err: any, binding: nbind.Binding\u003ctypeof LibTypes\u003e) =\u003e {\n  const lib = binding.lib;\n\n  // Use the library.\n});\n```\n\nPromise-based:\n\n```TypeScript\nimport * as bluebird from 'bluebird';\n\nbluebird.promisify(nbind.init)().then((binding: nbind.Binding\u003ctypeof LibTypes\u003e) =\u003e {\n  const lib = binding.lib;\n\n  // Use the library.\n});\n```\n\nNote how there is a type argument `\u003ctypeof LibTypes\u003e` for the init call\nin all of the examples. It defines types of `binding.lib` contents, which\ncoming from C++ are otherwise unknown to the TypeScript compiler.\nYou can import the types from a file generated by `ndts` or just use `\u003cany\u003e`\nto disable typing.\n\nFor example if you have a C++ class:\n\n```C++\nstruct C : public A, public B {\n    A *getA();\n\n    static uint32_t reticulate();\n};\n```\n\nAnd bind it like:\n\n```C++\nNBIND_CLASS(C) {\n    inherit(A);\n    inherit(B);\n\n    construct\u003c\u003e();\n\n    method(reticulate);\n\n    getter(getA);\n}\n```\n\n`ndts` will generate the following typings:\n\n```TypeScript\nexport interface _C extends A, B {}\nexport var _C: { new(): _C };\n\nexport class C extends _C {\n    /** C(); */\n    constructor();\n\n    /** static uint32_t reticulate(); */\n    static reticulate(): number;\n\n    /** A * a; -- Read-only */\n    a: A;\n}\n```\n\nThe additional interface `_C` is generated in this case to support multiple\ninheritance, because `C` extends both `A` and `B`.\n\nAll the [tests](https://github.com/charto/nbind/blob/master/test/test.ts)\nare written in TypeScript so if you run:\n\n```bash\ngit clone https://github.com/charto/nbind.git\ncd nbind\nnpm install\nnpm test\n```\n\nYou can then open `test/test.ts` in a TypeScript IDE and see the generated\ntypings in action.\n\nBinding plain C\n---------------\n\nnbind generates bindings using C++ templates for compile-time introspection\nof argument and return types of functions and methods.\n\nSince plain C doesn't have templates, there's no standard way to have a\nC compiler generate new wrapper code for type conversion and output type\ninformation available at run-time.\n\nThe easiest way to use nbind with C is to write a C++ wrapper calling\nthe C code, and use nbind with that.\n\nMapping idiomatic C to JavaScript classes may require some manual work,\nsince it's common to reinvent new ways to do object-oriented programming,\nusually by using structs as classes and simulating methods by passing struct\npointers to functions. C++ classes and methods should be used for these.\n\nA good example is [libui-node](https://github.com/parro-it/libui-node) which\nuses nbind to generate bindings for [libui](https://github.com/andlabs/libui),\nmainly a C library.\n\nBinding external libraries\n--------------------------\n\nIf you have external library source code, you should compile it separately\ninto a library first, and then link your Node.js addon with it. If the\nlibrary has an installation script and the addon is only intended for your\nown use or other users are willing to do some extra steps, it's easiest to\ninstall the library globally first.\n\nFor best user experience, [libui-node](https://github.com/parro-it/libui-node)\nis an example of distributing an external library together with your package.\n\nFor creating the actual bindings, see for example\n[this](https://github.com/charto/nbind/issues/35#issuecomment-259480287) and\n[this](https://github.com/charto/nbind/issues/35#issuecomment-260106802)\nmessage and [a tutorial](https://github.com/charto/nbind/blob/master/doc/vg-tutorial.md)\nfor getting the [`vg`](https://github.com/vgteam/vg) library working.\n\nDebugging\n---------\n\nIn the browser it can be difficult to stop and debug at the correct spot in\noptimized C++ code. `nbind` provides an `_nbind_debug()` function in `api.h`\nthat you can call from C++ to invoke the browser's debugger when using asm.js.\n\nFor debugging a Node.js addon, if you would normally test it like\n`node test.js`, you can instead use `gdb node` and type `run test.js` in the\nGDB prompt. Then in case of a crash, it will show where it happened,\ninspect the stack etc.\n\nYou should also modify `nbind.gypi` (inside nbind's `src` directory)\nand possibly your own `binding.gyp`, to remove any `-O?` flags and instead\nadd a `-g` flag, then remove the `build` directory and recompile.\nThis allows GDB to show much more information.\n\nAlternatives\n------------\n\nVery similar:\n\n- [Embind](https://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/embind.html)\n- [v8pp](https://github.com/pmed/v8pp)\n\nLess similar:\n\n- [libembindcefv8](https://github.com/gogoprog/libembindcefv8)\n- [node-ffi](https://github.com/node-ffi/node-ffi)\n- [cbind](https://github.com/encharm/node-cbind)\n- [cpgf](https://github.com/cpgf/cpgf)\n- [n2o](https://github.com/agnat/n2o)\n\nAuthors\n=======\n\n- Juha Järvi, befunge\u003cimg src=\"doc/images/gmail.png\" alt=\"domain\" width=\"87\" height=\"16\" align=\"absmiddle\"\u003e\n\nLicense\n=======\n\n[The MIT License](https://raw.githubusercontent.com/charto/nbind/master/LICENSE)\n\nCopyright (c) 2014-2017 BusFaster Ltd\n","funding_links":[],"categories":["C++","TODO scan for Android support in followings","Scripting","正则表达式"],"sub_categories":["脚本"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcharto%2Fnbind","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcharto%2Fnbind","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcharto%2Fnbind/lists"}