jsbind is a C++
!!!NOTE:
This repository is still a work in progress. Even though we use the library in production, it's nowhere near open-source friendly (yet). We'll be working to change that in the following weeks. So, until this note is gone, please accept that the version you see here has no documentation and no support.
Allows the users to have C++ bindings with the same codebase to the following JavaScript backends:
- node.js C++ Addons
- Pure v8
- Emscripten
- CEF
- JavaScriptCore
Supports:
- Executing JS code
- JS object creation
- Calling of JS functions
- Exposing C++ functions to JS
- Seamless integration of C++ built-in types and
std::string
- Defining custom value types for seamless integration
- Sharing memory between JS ArrayBuffer-s and C++
- C++11 compatible
We had a very complex stack for Mayhem. It's a game with a C++ engine with some elements of the gameplay and pretty muche the entire metagame logic in JavaScript. The target platforms for playing the game were iOS and Android. We also supported the browser as a target though not for playing the game, but for spectating and watching replays. The development platforms were Windows, macOS and Linux. The game's server ran on a Linux containter. We also had an editor written in JavaScript which could run in a browser or as a local application on a custom Chromium browser (through CEF) with the engine embedded inside. The server was in node.js and ran the engine as a native Addon.
Eventually we had a core in C++ and JavaScript which we wanted to run on all those platforms. Initially we had the C++/JS bidning layer written in concrete ways for all platforms, but this quickly got out of hand. So, we created jsbind: a binding library which lets you support all those platforms with a single codebase.
JS is a very popular language. There is no doubt that other developers want to combine it with C++. If they have similar complex stacks, perhaps it can be of help to them.
Add this repository to your project's directory structure either as a submodule or as a copy.
- Set exactly one of these CMake options to
TRUE
to describe the desired JS backend. This can be done with the command line or in yourCMakeLists.txt
files:JSBIND_NODE
for node.jsJSBIND_V8
for pure v8JSBIND_EMSCRIPTEN
for emscriptenJSBIND_CEF
for CEFJSBIND_JSC
for JavaScriptCore
- optionally set
JSBIND_JS_BACKEND_LIBS
to the one or more targets which describe the JS backend.- This is not needed for emscripten
- For the other backends, if you do not set this, you will have to use
include_directories
to set the appropriate include directories for jsbind and then link your targets with the appropriate libraries.
add_subdirectory(path/to/jsbind/subdir)
to add the jsbind static library target.
A full reference of all functions and classes is available here.
Here are some backend specific instructions for integrating jsbind:
For node.js the library cannot create the JS engine context, so it can only be initialized with jsbind::v8_initialize_with_global
. There is a simple example of doing so the node.js specific test file.
Do not forget to deinitialize jsbind or you may get a crash because of dangling v8 refs when exiting. node::AtExit
is probably the way to go. Again there is a simple example of using it in the node.js specific test file.
The library can create or be bound to a single v8 context. Multiple contexts are currently not supported.
You need to link emscripten "executables" which use jsbind with the --bind
linker flag.
jsbind can only run on a render process in CEF and is bound to a single CEF frame (iframe
). The frame in CEF is the unit which owns a distinct JS v8 context and they can't be shared.
The library can be bound to a single CEF frame and its context. Multiple contexts are currently not supported, though if you run in multiple processes (as you should) you can have a jsbind instance for each of them.
The library can create or be bound to a single JSC context. Multiple contexts are currently not supported.
Contributions are welcome.
The follwing links have instructions for how to set up your environment to build the tests and examples included in the repo.
jsbind lacks some features compared to other language binding libaries. Notably it doesn't allow users to seamlessly expose C++ classes to the language. The authors believe this prevents the creation of hard to find bugs and unorthodox object lifetimes for C++ objects.
Still if you absolutely need such features, to our knowledge no solution exists which supports that many backends. However if you're satisfied with a single backend (or two since node and v8 often come hand in hand), here is a list of more feature-rich single-backend libraries:
- v8pp - C++ bindings to v8 and node.js
Copyright © 2019 Chobolabs Inc.
This library is distributed under the MIT Software License. See LICENSE.txt for further details or copy here.