1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/tjopenlab-como_v8pp

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

v8pp

Библиотека только для заголовков, предназначенная для предоставления классов и функций C++ в V8 для использования в коде JavaScript. Для работы с v8pp требуется компилятор с поддержкой C++14. Библиотека была протестирована на:

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

Пример привязки

v8pp поддерживает версии V8 после 6.3 с использованием v8::Isolate в API. Существует две цели для привязки:

  1. v8pp::module, класс-оболочка вокруг v8::ObjectTemplate.
  2. v8pp::class_, шаблон класса-оболочки вокруг v8::FunctionTemplate.

Оба требуют указателя на экземпляр v8::Isolate. Они позволяют связывать из кода C++ такие элементы, как переменные, функции, константы, с помощью функции 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; } 
};

// связываем свободные переменные и функции
v8pp::module mylib(isolate);
mylib
    // устанавливаем атрибут read-only
    .set_const("PI", 3.1415)
    // устанавливаем переменную, доступную в JavaScript с именем `var`
    .set("var", var)
    // устанавливаем функцию get_var как `fun`
    .set("fun", &get_var)
    // устанавливаем свойство `prop` с геттером get_var() и сеттером set_var()
    .set("prop", property(get_var, set_var));

// привязываем класс
v8pp::class_<X> X_class(isolate);
X_class
    // указываем сигнатуру конструктора X
    .ctor<int, bool>()
    // связываем переменную
    .set("var", &X::var)
    // связываем функцию
    .set("fun", &X::set)
    // связываем свойство read-only
    .set("prop", property(&X::get));

// устанавливаем класс в шаблон модуля
mylib.set("X", X_class);

// устанавливаем привязки в глобальном объекте как `mylib`
isolate->GetCurrentContext()->Global()->Set(
    v8::String::NewFromUtf8(isolate, "mylib"), mylib.new_instance());

После этого привязки будут доступны в JavaScript:

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

Надстройки Node.js и io.js

Библиотека подходит для создания надстроек Node.js и io.js. См. документ addons.


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

    // устанавливаем привязки... 
    addon
        .set("fun", &function)
        .set("cls", my_class)
        ;

    // устанавливаем привязки как прототип объекта экспорта
    exports->SetPrototype(addon.new_instance());
}

v8pp также предоставляет

  • v8pp — статическую библиотеку для добавления нескольких глобальных функций (загрузка/требование в контекст JavaScript V8. Функция require() — это система загрузки плагинов из общих библиотек.
  • test — двоичный файл для запуска файлов JavaScript в контексте, в котором предоставлены функции загрузки модулей v8pp.

Пример модуля v8pp

#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

Превращение модуля v8pp в плагин v8pp

V8PP_PLUGIN_INIT(v8::Isolate* isolate)
{
    return console::init(isolate);
}
``` **Пример привязки класса v8pp**

```c++
#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);
}

Создание контекста v8, способного использовать функцию require()

#include <v8pp/context.hpp>

v8pp::context context;
context.set_lib_path("path/to/plugins/lib");
// скрипт теперь может использовать функцию require(). Приложение,
// использующее v8pp::context, должно ссылаться на библиотеку v8pp.
v8::HandleScope scope(context.isolate());
context.run_file("some_file.js");

Использование require() из JavaScript

// Загрузить модуль файла из примера привязки классов и модуль консоли.
var file    = require('file'),
    console =
``` **Требуется функция console**

```var writer = new file.writer("file")```

Если (writer.is_open()), то:

    * writer.println("some text");
    * writer.close();
    * если (! file.rename("file", "newfile")), то console.log("не удалось переименовать файл").

Иначе console.log("не удалось открыть `file'").

Console.log("exit").

## Создание дескриптора для класса C++, на который есть внешняя ссылка

```// Память для класса C++ останется, когда объект JavaScript будет удалён.
// Полезно для классов, которые вы хотите только внедрить.
typedef v8pp::class_<my_class> my_class_wrapper;
v8::Local<v8::Value> val = my_class_wrapper::reference_external(isolate, &my_class::instance());
// Предполагается, что my_class::instance() возвращает ссылку на класс```

## Импорт класса C++, созданного извне, в v8pp

```// Память для объекта C++ будет освобождена JavaScript с помощью "delete", когда
// класс JavaScript будет удалён.
typedef v8pp::class_<my_class> my_class_wrapper;
v8::Local<v8::Value> val = my_class_wrapper::import_external(isolate, new my_class);```

## Конфигурация во время компиляции

Библиотека использует несколько макросов препроцессора, определённых в файле `v8pp/config.hpp`:

  * `V8PP_ISOLATE_DATA_SLOT` — номер слота данных v8::Isolate, используемый для хранения внутренних данных v8pp.
  * `V8PP_PLUGIN_INIT_PROC_NAME` — имя процедуры инициализации плагина, которая должна быть экспортирована из плагина v8pp.
  * `V8PP_PLUGIN_SUFFIX` — суффикс имени файла плагина, который будет добавлен, если имя плагина, используемое в `require()`, не заканчивается им.
  * `V8PP_HEADER_ONLY` — использование реализации только для заголовков, включено по умолчанию.

## Альтернативы v8pp
* [nbind](https://github.com/charto/nbind)
* [vu8](https://github.com/tsa/vu8), заброшенный
* [v8-juice](http://code.google.com/p/v8-juice/), заброшенный
* Связывание скриптов в [cpgf](https://github.com/cpgf/cpgf).

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

Как библиотека привязки к JavaScript, движок V8. Развернуть Свернуть
BSL-1.0
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/tjopenlab-como_v8pp.git
git@api.gitlife.ru:oschina-mirror/tjopenlab-como_v8pp.git
oschina-mirror
tjopenlab-como_v8pp
tjopenlab-como_v8pp
master