MCPcopy Create free account
hub / github.com/charto/nbind

github.com/charto/nbind @v0.3.15

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.3.15 ↗ · + Follow
927 symbols 1,344 edges 102 files 12 documented · 1% updated 7y agov0.3.15 · 2018-03-02★ 2,00062 open issues

Browse by type

Functions 614 Types & classes 313
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Quick start | Requirements | Features | User guide | Contributing | License

nbind flowchart

nbind is a set of headers that make your C++11 library accessible from JavaScript. With a single #include statement, your C++ compiler generates the necessary bindings without any additional tools. Your library is then usable as a Node.js addon or, if compiled to asm.js with Emscripten, directly in web pages without any plugins.

nbind works with the autogypi dependency management tool, which sets up node-gyp to compile your library without needing any configuration (other than listing your source code file names).

nbind is MIT licensed and based on templates and macros inspired by embind.

Quick start

C++ everywhere in 5 easy steps using Node.js, nbind and autogypi:

Starting point Step 1 - bind Step 2 - prepare
Original C++ code hello.cc:
#include <string>
#include <iostream>
 
struct Greeter {
  static void sayHello(
    std::string name
  ) {
    std::cout
      << "Hello, "
      << name << "!\n";
  }
};
List your classes and methods:
// Your original code here
 
// Add these below it:
 
#include "nbind/nbind.h"
 
NBIND_CLASS(Greeter) {
  method(sayHello);
}
Add scripts to package.json:
{
  "scripts": {
    "autogypi": "autogypi",
    "node-gyp": "node-gyp",
    "emcc-path": "emcc-path",
    "copyasm": "copyasm",
    "ndts": "ndts"
  }
}
Step 3 - install Step 4 - build Step 5 - use!
Run on the command line:
npm install --save \
  nbind autogypi node-gyp
 
npm run -- autogypi \
  --init-gyp \
  -p nbind -s hello.cc
Compile to native binary:
npm run -- node-gyp \
  configure build
Or to Asm.js:
npm run -- node-gyp \
  configure build \
  --asmjs=1
Call from Node.js:
var nbind = require('nbind');
var lib = nbind.init().lib;
 
lib.Greeter.sayHello('you');
Or from a web browser (see below).

The above is all of the required code. Just copy and paste in the mentioned files and prompts or take a shortcut:

git clone https://github.com/charto/nbind-example-minimal.git
cd nbind-example-minimal
npm install && npm test

See it run!

(Note: nbind-example-universal is a better starting point for development)

Requirements

You need:

And one of the following C++ compilers:

  • GCC 4.8 or above.
  • Clang 3.6 or above.
  • Emscripten 1.35.0 or above.
  • Visual Studio 2015 (the Community version is fine).

Features

nbind allows you to:

  • Use your C++ API from JavaScript without any extra effort.
  • From Node.js, Electron and web browsers (using asm.js on Chrome, Firefox and Edge).
  • On Linux, OS X and Windows.
  • Without changes to your C++ code. Simply add a separate short description at the end.
  • Distribute both native code and an asm.js fallback binary.
  • Automatically generate TypeScript .d.ts definition files from C++ code for IDE autocompletion and compile-time checks of JavaScript side code.

In more detail:

  • Export multiple C++ classes, even ones not visible from other files.
  • Export C++ methods simply by mentioning their names.
  • Auto-detect argument and return types from C++ declarations.
  • Automatically convert types and data structures between languages.
  • Call C++ methods from JavaScript with type checking.
  • Pass JavaScript callbacks to C++ and call them with any types.
  • Pass instances of compatible classes by value between languages (through the C++ stack).

The goal is to provide a stable API for binding C++ to JavaScript. All internals related to JavaScript engines are hidden away, and a single API already supports extremely different platforms.

Works on your platform

Target Development platform
Linux / OS X Windows
Native Build status Build status
Asm.js Build status Tested manually

dependency status npm version

Roadmap

More is coming! Work is ongoing to:

  • Precompile to a single native library for all versions Node.js and Electron on the same platform
  • Precompiled addons for different Node.js versions for efficiently calling the library will be provided with nbind
  • Support native Android and iPhone apps.

Future 0.x.y versions should remain completely backwards-compatible between matching x and otherwise with minor changes. Breaking changes will be listed in release notes of versions where y equals 0.

Contributing

Please report issues through Github and mention the platform you're targeting (Node.js, asm.js, Electron or something else). Pull requests are very welcome.

Warning: rebase is used within develop and feature branches (but not master).

When developing new features, writing tests first works best. If possible, please try to get them working on both Node.js and asm.js. Otherwise your pull request will get merged to Master only after maintainer(s) have fixed the other platform.

Installing Emscripten to develop for asm.js can be tricky. It will require Python 2.7 and setting paths correctly, please refer to Emscripten documentation. The bin/emcc script in this package is just a wrapper, the actual emcc compiler binary should be in your path.

You can rebuild the asm.js library and run tests as follows:

npm run clean-asm && npm run prepublish && npm run test-asm

User guide

Installing the examples

nbind examples shown in this user guide are also available to download for easier testing as follows:

Extract this zip package or run:

git clone https://github.com/charto/nbind-examples.git

Enter the examples directory and install:

cd nbind-examples
npm install

Creating your project

Once you have all requirements installed, run:

npm init
npm install --save nbind autogypi node-gyp

nbind, autogypi and node-gyp are all needed to compile a native Node.js addon from source when installing it. If you only distribute an asm.js version, you can use --save-dev instead of --save because users won't need to compile it.

Next, to run commands without installing them globally, it's practical to add them in the scripts section of your package.json that npm init just generated. Let's add an install script as well:

  "scripts": {
    "autogypi": "autogypi",
    "node-gyp": "node-gyp",
    "emcc-path": "emcc-path",
    "copyasm": "copyasm",

    "install": "autogypi && node-gyp configure build"
  }

emcc-path is needed internally by nbind when compiling for asm.js. It fixes some command line options that node-gypi generates on OS X and the Emscripten compiler doesn't like. You can leave it out if only compiling native addons.

The install script runs when anyone installs your package. It calls autogypi and then uses node-gyp to compile a native addon.

autogypi uses npm package information to set correct include paths for C/C++ compilers. It's needed when distributing addons on npm so the compiler can find header files from the nbind and nan packages installed on the user's machine. Initialize it like this:

npm run -- autogypi --init-gyp -p nbind -s hello.cc

Replace hello.cc with the name of your C++ source file. You can add multiple -s options, one for each source file.

The -p nbind means the C++ code uses nbind. Multiple -p options can be added to add any other packages compatible with autogypi.

The --init-gyp command generates files binding.gyp and autogypi.json that you should distribute with your package, so that autogypi and node-gyp will know what to do when the install script runs.

Now you're ready to start writing code and compiling.

Configuration

Refer to autogypi documentation to set up dependencies of your package, and how other packages should include it if it's a library usable directly from C++.

--asmjs=1 is the only existing configuration option for nbind itself. You pass it to node-gyp by calling it like node-gyp configure build --asmjs=1. It compiles your package using Emscripten instead of your default C++ compiler and produces asm.js output.

Calling from Node.js

First nbind needs to be initialized by calling nbind.init which takes the following optional arguments:

  • Base path under which to look for compiled binaries. Default is process.cwd() and __dirname is a good alternative.
  • Binary code exports object. Any classes from C++ API exported using nbind will be added as members. Default is an empty object. Any existing options will be seen by asm.js code and can be used to configure Emscripten output. Must follow base path (which may be set to null or undefined).
  • Node-style callback with 2 parameters:
  • Error if present, otherwise null.
  • Binary code exports object containing C++ classes.

nbind can be initialized synchronously on Node.js and asynchronously on browsers and Node.js. Purely synchronous is easier but not as future-proof:

var nbind = require('nbind');
var lib = nbind.init().lib;

// Use the library.

Using a callback also supports asynchronous initialization:

var nbind = require('nbind');

nbind.init(function(err, binding) {
  var lib = binding.lib;

  // Use the library.
});

The callback passed to init currently gets called synchronously in Node.js and asynchronously in browsers. To avoid releasing zalgo you can for example wrap the call in a bluebird promise:

var bluebird = require('bluebird');
var nbind = require('nbind');

bluebird.promisify(nbind.init)().then(function(binding) {
  var lib = binding.lib;

  // Use the library.
});

Using nbind headers

There are two possible files to include:

  • nbind/api.h for using types from the nbind namespace such as JavaScript callbacks inside your C++ code.
  • #include before your own class definitions.
  • Causes your code to depend on nbind.
  • nbind/nbind.h for exposing your C++ API to JavaScript

Extension points exported contracts — how you extend this code

Core symbols most depended-on inside this repo

Shape

Method 493
Class 292
Function 121
Interface 13
Enum 8

Languages

C++70%
TypeScript30%

Modules by API surface

include/nbind/Policy.h37 symbols
src/reflect.ts36 symbols
test/PrimitiveMethods.cc29 symbols
include/nbind/em/Callback.h27 symbols
include/nbind/BindClass.h26 symbols
src/em/BindClass.ts25 symbols
test/Inheritance.cc24 symbols
include/nbind/v8/BindingType.h24 symbols
include/nbind/v8/BindWrapper.h23 symbols
include/nbind/em/BindingType.h23 symbols
src/em/BindingType.ts21 symbols
src/Type.ts21 symbols

For agents

$ claude mcp add nbind \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page