Библиотека только для заголовков, предназначенная для предоставления классов и функций C++ в V8 для использования в коде JavaScript. Для работы с v8pp требуется компилятор с поддержкой C++14. Библиотека была протестирована на:
v8pp поддерживает версии V8 после 6.3 с использованием v8::Isolate
в API. Существует две цели для привязки:
v8pp::module
, класс-оболочка вокруг v8::ObjectTemplate
.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. См. документ 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
— статическую библиотеку для добавления нескольких глобальных функций (загрузка/требование в контекст JavaScript V8. Функция require()
— это система загрузки плагинов из общих библиотек.test
— двоичный файл для запуска файлов JavaScript в контексте, в котором предоставлены функции загрузки модулей 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_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 )