All Projects → pmed → V8pp

pmed / V8pp

Licence: other
Bind C++ functions and classes into V8 JavaScript engine

Programming Languages

javascript
184084 projects - #8 most used programming language
cpp
1120 projects
cpp17
186 projects
cpp14
131 projects

Labels

Projects that are alternatives of or similar to V8pp

addon-example
Example - Home Assistant Community Add-ons
Stars: ✭ 73 (-88.65%)
Mutual labels:  addons
addon-appdaemon
AppDaemon4 - Home Assistant Community Add-ons
Stars: ✭ 66 (-89.74%)
Mutual labels:  addons
Addons Frontend
Front-end to complement mozilla/addons-server
Stars: ✭ 478 (-25.66%)
Mutual labels:  addons
addon-base-python
Docker Python base images (Alpine) - Home Assistant Community Add-ons
Stars: ✭ 12 (-98.13%)
Mutual labels:  addons
forge
🔥 Incubator of pet projects, tools, pet projects. Edge cases and failovers included.
Stars: ✭ 33 (-94.87%)
Mutual labels:  addons
addon-mopidy
Mopidy - Home Assistant Community Add-ons
Stars: ✭ 42 (-93.47%)
Mutual labels:  addons
addon-matrix
Matrix - Home Assistant Community Add-ons
Stars: ✭ 39 (-93.93%)
Mutual labels:  addons
Ramda Adjunct
Ramda Adjunct is the most popular and most comprehensive set of functional utilities for use with Ramda, providing a variety of useful, well tested functions with excellent documentation.
Stars: ✭ 550 (-14.46%)
Mutual labels:  addons
HackBar
HackBar is a security audit tool that will enable you to pentest websites more easily. ... You can use it to check site security by performing SQL injections, XSS holes and more. It also has a user-friendly interface that makes it easy for you to do fuzz testing, hash generation, encoding and more.
Stars: ✭ 43 (-93.31%)
Mutual labels:  addons
Nest Router
Router Module For Nestjs Framework 🚦 🚀
Stars: ✭ 403 (-37.33%)
Mutual labels:  addons
mightyscape-1.X
A maintained extension collection for Inkscape 1.0+, working on Windows and Linux
Stars: ✭ 23 (-96.42%)
Mutual labels:  addons
addon-airsonos
AirSonos - Home Assistant Community Add-ons
Stars: ✭ 50 (-92.22%)
Mutual labels:  addons
Freecad Addons
A convenient gathering of useful and well-developed FreeCAD plugins made by the community.
Stars: ✭ 365 (-43.23%)
Mutual labels:  addons
stay-productive
Remove feed from Facebook, Twitter and Linkedin... To stay productive !
Stars: ✭ 15 (-97.67%)
Mutual labels:  addons
Repository
Home Assistant Community Add-ons
Stars: ✭ 520 (-19.13%)
Mutual labels:  addons
addon-traccar
Traccar - Home Assistant Community Add-ons
Stars: ✭ 65 (-89.89%)
Mutual labels:  addons
odoo-demo-addons-tutorial
學習 odoo , 本文章會持續更新
Stars: ✭ 52 (-91.91%)
Mutual labels:  addons
Minecraftdeveloperguide
📝Minecraft developer Chinese guide,我的世界开发者中文指南
Stars: ✭ 574 (-10.73%)
Mutual labels:  addons
Redux Ecosystem Links
A categorized list of Redux-related addons, libraries, and utilities
Stars: ✭ 5,076 (+689.42%)
Mutual labels:  addons
Ca Archive
Catalog of classic Firefox add-ons created before WebExtensions apocalypse
Stars: ✭ 383 (-40.44%)
Mutual labels:  addons

Travis Build status AppVeyor build status NPM Join the chat at https://gitter.im/pmed/v8pp

v8pp

Header-only library to expose C++ classes and functions into V8 to use them in JavaScript code. v8pp requires a compiler with C++14 support. The library has been tested on:

  • Microsoft Visual C++ 2019 (Windows 10)
  • GCC 5.4.0 (Ubuntu 16.04)
  • Clang 5.0.0 (Ubuntu 16.04)

Binding example

v8pp supports V8 versions after 6.3 with v8::Isolate usage in API. There are 2 targets for binding:

  • v8pp::module, a wrapper class around v8::ObjectTemplate
  • v8pp::class_, a template class wrapper around v8::FunctionTemplate

Both of them require a pointer to v8::Isolate instance. They allows to bind from C++ code such items as variables, functions, constants with a function set(name, item):

v8::Isolate* isolate;

int var;
int get_var() { return var + 1; }
void set_var(int x) { var = x + 1; }

struct X
{
    X(int v, bool u) : var(v) {}
    int var;
    int get() const { return var; }
    void set(int x) { var = x; } 
};

// bind free variables and functions
v8pp::module mylib(isolate);
mylib
    // set read-only attribute
    .set_const("PI", 3.1415)
    // set variable available in JavaScript with name `var`
    .set("var", var)
    // set function get_var as `fun`
    .set("fun", &get_var)
    // set property `prop` with getter get_var() and setter set_var()
    .set("prop", property(get_var, set_var));

// bind class
v8pp::class_<X> X_class(isolate);
X_class
    // specify X constructor signature
    .ctor<int, bool>()
    // bind variable
    .set("var", &X::var)
    // bind function
    .set("fun", &X::set)
    // bind read-only property
    .set("prop", property(&X::get));

// set class into the module template
mylib.set("X", X_class);

// set bindings in global object as `mylib`
isolate->GetCurrentContext()->Global()->Set(
    v8::String::NewFromUtf8(isolate, "mylib"), mylib.new_instance());

After that bindings will be available in JavaScript:

mylib.var = mylib.PI + mylib.fun();
var x = new mylib.X(1, true);
mylib.prop = x.prop + x.fun();

Node.js and io.js addons

The library is suitable to make Node.js and io.js addons. See addons document.

void RegisterModule(v8::Local<v8::Object> exports)
{
    v8pp::module addon(v8::Isolate::GetCurrent());

    // set bindings... 
    addon
        .set("fun", &function)
        .set("cls", my_class)
        ;

    // set bindings as exports object prototype
    exports->SetPrototype(addon.new_instance());
}

v8pp also provides

  • v8pp - a static library to add several global functions (load/require to the v8 JavaScript context. require() is a system for loading plugins from shared libraries.
  • test - A binary for running JavaScript files in a context which has v8pp module loading functions provided.

v8pp module example

#include <iostream>

#include <v8pp/module.hpp>

namespace console {

void log(v8::FunctionCallbackInfo<v8::Value> const& args)
{
    v8::HandleScope handle_scope(args.GetIsolate());

    for (int i = 0; i < args.Length(); ++i)
    {
        if (i > 0) std::cout << ' ';
        v8::String::Utf8Value str(args[i]);
        std::cout <<  *str;
    }
    std::cout << std::endl;
}

v8::Local<v8::Value> init(v8::Isolate* isolate)
{
    v8pp::module m(isolate);
    m.set("log", &log);
    return m.new_instance();
}

} // namespace console

Turning a v8pp module into a v8pp plugin

V8PP_PLUGIN_INIT(v8::Isolate* isolate)
{
    return console::init(isolate);
}

v8pp class binding example

#include <v8pp/module.hpp>
#include <v8pp/class.hpp>

#include <fstream>

namespace file {

bool rename(char const* src, char const* dest)
{
    return std::rename(src, dest) == 0;
}

class file_base
{
public:
    bool is_open() const { return stream_.is_open(); }
    bool good() const { return stream_.good(); }
    bool eof() const { return stream_.eof(); }
    void close() { stream_.close(); }

protected:
    std::fstream stream_;
};

class file_writer : public file_base
{
public:
    explicit file_writer(v8::FunctionCallbackInfo<v8::Value> const& args)
    {
        if (args.Length() == 1)
        {
            v8::String::Utf8Value str(args[0]);
            open(*str);
        }
    }

    bool open(char const* path)
    {
        stream_.open(path, std::ios_base::out);
        return stream_.good();
    }

    void print(v8::FunctionCallbackInfo<v8::Value> const& args)
    {
        v8::HandleScope scope(args.GetIsolate());

        for (int i = 0; i < args.Length(); ++i)
        {
            if (i > 0) stream_ << ' ';
            v8::String::Utf8Value str(args[i]);
            stream_ << *str;
        }
    }

    void println(v8::FunctionCallbackInfo<v8::Value> const& args)
    {
        print(args);
        stream_ << std::endl;
    }
};

class file_reader : public file_base
{
public:
    explicit file_reader(char const* path)
    {
        open(path);
    }

    bool open(const char* path)
    {
        stream_.open(path, std::ios_base::in);
        return stream_.good();
    }

    v8::Local<v8::Value> getline(v8::Isolate* isolate)
    {
        if ( stream_.good() && ! stream_.eof())
        {
            std::string line;
            std::getline(stream_, line);
            return v8pp::to_v8(isolate, line);
        }
        else
        {
            return v8::Undefined(isolate);
        }
    }
};

v8::Local<v8::Value> init(v8::Isolate* isolate)
{
    v8::EscapableHandleScope scope(isolate);

    // file_base binding, no .ctor() specified, object creation disallowed in JavaScript
    v8pp::class_<file_base> file_base_class(isolate);
    file_base_class
        .set("close", &file_base::close)
        .set("good", &file_base::good)
        .set("is_open", &file_base::is_open)
        .set("eof", &file_base::eof)
        ;

    // .ctor<> template arguments declares types of file_writer constructor
    // file_writer inherits from file_base_class
    v8pp::class_<file_writer> file_writer_class(isolate);
    file_writer_class
        .ctor<v8::FunctionCallbackInfo<v8::Value> const&>()
        .inherit<file_base>()
        .set("open", &file_writer::open)
        .set("print", &file_writer::print)
        .set("println", &file_writer::println)
        ;

    // .ctor<> template arguments declares types of file_reader constructor.
    // file_base inherits from file_base_class
    v8pp::class_<file_reader> file_reader_class(isolate);
    file_reader_class
        .ctor<char const*>()
        .inherit<file_base>()
        .set("open", &file_reader::open)
        .set("getln", &file_reader::getline)
        ;

    // Create a module to add classes and functions to and return a
    // new instance of the module to be embedded into the v8 context
    v8pp::module m(isolate);
    m.set("rename", &rename)
     .set("writer", file_writer_class)
     .set("reader", file_reader_class)
        ;

    return scope.Escape(m.new_instance());
}

} // namespace file

V8PP_PLUGIN_INIT(v8::Isolate* isolate)
{
    return file::init(isolate);
}

Creating a v8 context capable of using require() function

#include <v8pp/context.hpp>

v8pp::context context;
context.set_lib_path("path/to/plugins/lib");
// script can now use require() function. An application
// that uses v8pp::context must link against v8pp library.
v8::HandleScope scope(context.isolate());
context.run_file("some_file.js");

Using require() from JavaScript

// Load the file module from the class binding example and the
// console module.
var file    = require('file'),
    console = require('console')

var writer = new file.writer("file")
if (writer.is_open()) {
    writer.println("some text")
    writer.close()
    if (! file.rename("file", "newfile"))
        console.log("could not rename file")
}
else console.log("could not open `file'")

console.log("exit")

Create a handle to an externally referenced C++ class.

// Memory for C++ class will remain when JavaScript object is deleted.
// Useful for classes you only wish to inject.
typedef v8pp::class_<my_class> my_class_wrapper;
v8::Local<v8::Value> val = my_class_wrapper::reference_external(isolate, &my_class::instance());
// Assuming my_class::instance() returns reference to class

Import externally created C++ class into v8pp.

// Memory for c++ object will be reclaimed by JavaScript using "delete" when
// JavaScript class is deleted.
typedef v8pp::class_<my_class> my_class_wrapper;
v8::Local<v8::Value> val = my_class_wrapper::import_external(isolate, new my_class);

Compile-time configuration

The library uses several preprocessor macros, defined in v8pp/config.hpp file:

  • V8PP_ISOLATE_DATA_SLOT - A v8::Isolate data slot number, used to store v8pp internal data
  • V8PP_PLUGIN_INIT_PROC_NAME - Plugin initialization procedure name that should be exported from a v8pp plugin.
  • V8PP_PLUGIN_SUFFIX - Plugin filename suffix that would be added if the plugin name used in require() doesn't end with it.
  • V8PP_HEADER_ONLY - Use header-only implemenation, enabled by default.

v8pp alternatives

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].