Подводя из N давно - использование Node.js для реконструкции онлайн -судьи NBUT, включая сторону оценки, также необходимо реконструировать. (Что касается того, когда он завершен, не заботитесь, (/D ′)/~
Короче говоря, мы собираемся сделать сейчас, так это использовать C/C ++ для реализации модулей node.js.
Подготовка
Если вы хотите делать что -то хорошо, вы должны сначала вести себя как гангстер и обострить свои инструменты.
узел-гип
Сначала вам нужен модуль узла-гипа.
В любом углу выполнить:
Кода -копия выглядит следующим образом:
$ npm установить узлы -gyp -g
После серии блахблах вы установили его.
Питон
Тогда вам нужно иметь среду Python.
Зайдите на официальный сайт и получите один.
ПРИМЕЧАНИЕ. Согласно дисплею GitHub от Node-Gyp, обязательно убедитесь, что ваша версия Python находится между 2.5.0 и 3.0.0.
Компиляционная среда
Ну, я просто ленив и не пишу это подробно. Пожалуйста, перейдите в Node-Gyp, чтобы увидеть потребности компилятора. И суетиться.
начиная
Я расскажу вам о введении на официальный сайт Hello World.
Привет, мир
Пожалуйста, приготовьте файл C ++, например, он называется ~~ sb.cc ~~ hello.cc.
Затем мы сделаем шаг за шагом, сначала создадим файл заголовка и определим пространство имен:
Кода -копия выглядит следующим образом:
#include <node.h>
#include <v8.h>
Использование пространства имен V8;
Основные функции
Далее мы пишем функцию, возвращаемое значение, обратное значение <значение>.
Кода -копия выглядит следующим образом:
Обработка <значения> Привет (Const Arguments & Args)
{
// ... был голоден, чтобы быть написанным
}
Тогда я примерно проанализирую эти вещи:
Ручка <значение>
Вы должны быть честными в жизни. Я заранее заявляю, что ссылаюсь на это отсюда (@fool).
V8 использует тип ручки для размещения объектов JavaScript. Подобно C ++ STD :: SharedPointer, назначения между типами ручка передаются непосредственно ссылками на объекты, но разница в том, что V8 использует свой собственный GC для управления жизненным циклом объекта, а не подсчет ссылок, обычно используемых смарт -указателями.
Типы JavaScript имеют соответствующие пользовательские типы в C ++, такие как строка, целое число, объект, дата, массив и т. Д., И строго соблюдают отношения наследования в JavaScript. При использовании этих типов в C ++ вы должны использовать хостинг для использования GC для управления их жизненными циклами без использования собственных стеков и кучей.
Это так называемое значение, которое можно увидеть из различных отношений наследования в файле заголовка V8.H двигателя V8, на самом деле является базовым классом различных объектов в JavaScript.
Понимая это, мы можем приблизительно понять значение приведенного выше оператора функции, что означает, что мы пишем функцию Hello, которая возвращает значение неопределенного типа.
Примечание: мы можем вернуть только определенные типы, а именно строку, целое число и т. Д. Под управлением ручки.
Аргументы
Это параметр для передачи в этой функции. Мы все знаем, что в node.js количество параметров является случайным. Когда эти параметры передаются в C ++, они преобразуются в объект типа аргументов.
Давайте поговорим о конкретном использовании позже. Здесь нам просто нужно понять, что это такое. (Чтобы сохранить это в секрете? Потому что примеры в официальном документе Node.js обсуждаются отдельно. Я просто говорю о первом примере Hello World (´థ౪థ) σ
Добавить кирпичи и плитки
Далее мы начинаем вносить свой вклад. Просто самые простые предложения:
Кода -копия выглядит следующим образом:
Обработка <значения> Привет (Const Arguments & Args)
{
Групповой масштаб;
return scope.close (string :: new ("world"));
}
Что означают эти два предложения? Общее значение состоит в том, чтобы вернуть строку «мир» в node.js.
Грузом
Та же ссылка отсюда.
Жизненный цикл ручки отличается от цикла интеллектуальных указателей C ++. Он не выживает в рамках семантики C ++ (то есть часть, окруженная {}), но должна быть указана вручную с помощью ручного кожи. HandleScope может быть выделен только на стеке. После того, как объект HandlesCope объявлен, создаваемая позже ручка управляется HandleScope. После того, как объект HandlesCope будет разрушен, управляемая ручкой будет определено GC.
Итак, мы должны объявить эту область, когда нам нужно управлять его жизненным циклом. Хорошо, так почему бы наш код не был написан так?
Кода -копия выглядит следующим образом:
Обработка <значения> Привет (Const Arguments & Args)
{
Групповой масштаб;
return String :: new ("World");
}
Потому что, когда функция вернется, область применения будет разрушена, и ручки, которые она управляет, будут переработаны, поэтому эта строка станет бессмысленной.
Таким образом, V8 придумал магическую идею - функция HandleScope :: Close (Handle <T> значение)! Цель этой функции состоит в том, чтобы закрыть объем и передать параметры внутри предыдущего управления областями сферы, то есть сфера, прежде чем вступить в эту функцию.
Таким образом, у нас есть предыдущий код Scope.close (String :: new ("World"));.
String :: новая
Класс строки соответствует нативному классу строк в node.js. Унаследован от класса стоимости. Точно так же есть:
•Множество
• целое число
• логический
•Объект
•Дата
•Число
• функция
• ...
Некоторые из этих вещей унаследованы от стоимости, в то время как другие унаследованы от второстепенного. Мы не будем проводить здесь много исследований. Вы можете посмотреть на код V8 (по крайней мере, файл заголовка) или посмотреть на это руководство.
А как насчет этого нового? Вы можете увидеть это здесь. Это создание нового строкового объекта.
На этом этапе мы закончили анализ этой основной функции.
Экспортные объекты
Давайте рассмотрим это. Если он записан в node.js, как мы экспортируем функции или объекты?
Кода -копия выглядит следующим образом:
exports.hello = function () {}
Итак, как мы можем сделать это в C ++?
Инициализировать функцию
Во -первых, давайте напишем функцию инициализации:
Кода -копия выглядит следующим образом:
void init (ручка <объекта> экспорт)
{
// ... мне жажду писать о твоей сестре! #゚ Å ゚) ⊂ち☆)) ゚d ゚) ・∵
}
Это черепаха! Не имеет значения, если имя функции или что -то в этом роде, но падеб с передачей должен быть ручком <object>, что означает, что мы будем экспортировать вещи из этого продукта ниже.
Затем мы пишем здесь экспортируемую вещь:
Кода -копия выглядит следующим образом:
void init (ручка <объекта> экспорт)
{
экспорт-> set (string :: newsymbol ("hello"),
FunctionTemplate :: new (hello)-> getFunction ());
}
Общее значение состоит в том, чтобы добавить поле, называемое Hello, к этому объекту Exports, и соответствующая вещь - функция, и эта функция - наша функция дорогой привет.
Чтобы написать простую точку в псевдокоде:
Кода -копия выглядит следующим образом:
void init (ручка <объекта> экспорт)
{
exports.set ("Привет", функция привет);
}
Работа сделана!
(Твоя сестра сделана! Заткнись (',)) ДД)
Истинный экспорт
Это последний шаг, и мы наконец заявим, что это вход в экспорт, поэтому мы добавляем эту строку в конце кода:
Node_module (привет, init)
Вы взяли Ni? ! Что это?
Не волнуйтесь, этот node_module является макросом, что означает, что мы используем функцию инициализации инициализации инициализации инициализации для экспорта, которые будут экспортированы в Hello. Так откуда это привет?
Это происходит от имени файла! Да, да, это происходит от имени файла. Вам не нужно объявлять это заранее, и вам не нужно беспокоиться о том, чтобы не иметь возможности использовать его. Короче говоря, как называется ваш окончательный скомпилированный бинарный файл? Вы заполните Hello здесь, и, конечно, вам нужно удалить имя суффикса.
Смотрите официальную документацию для деталей.
Обратите внимание, что все добавления узла должны экспортировать функцию инициализации:
Кода -копия выглядит следующим образом:
void инициализируется (Randle <Object> exports);
Node_module (module_name, инициализировать)
После node_module нет полуколона, так как это не функция (см. Node.h).
Module_Name должен соответствовать имени файла окончательного двоичного файла (минус суффикс .NODE).
Компилирование (๑ • ́ ₃ • ̀๑)
Давай, давай компилируемся вместе!
Давайте создадим новый архивный файл, похожий на makefile - binding.gyp.
И добавьте код таким образом:
Кода -копия выглядит следующим образом:
{
«Цели»: [
{
"target_name": "Привет",
«Источники»: ["hello.cc"]
}
]
}
Зачем это писать? Вы можете обратиться к официальной документации Node-Gyp.
настройка
После того, как файл будет готов, нам нужно выполнить эту команду в этом каталоге:
Кода -копия выглядит следующим образом:
$ node-gyp configure
Если все в порядке, должен быть сгенерирован каталог сборки, и тогда внутри есть связанные файлы, возможно, M $ Visual Studio VCXPROJ File и т. Д., Или, возможно, Makefile, в зависимости от платформы.
строить
После создания Make -файла мы начинаем строить и компилировать:
$ node-gyp build
Только когда все будет составлено, будет рассмотрено, что реальная задача выполнена! Если вы не верите в это, идите и проверьте каталог сборки/выпуска. Есть ли ниже файл hello.node? Правильно, это мыло, которое C ++ хочет забрать для Node.js позже!
Давайте получим основы! Узел (✿゚゚) ノ C ++
Мы только сейчас создаем новый файл jianfeizao.js в каталоге:
Кода -копия выглядит следующим образом:
var addon = require ("./ build/release/hello");
console.log (addon.hello ());
Видите это или нет! Видите это или нет! Публично заявить! Результат node.js и c ++ получает основы! Этот addon.hello () - это ручка <значение> hello (const arguments & args), которые мы писали в коде C ++, и теперь мы выводем значение, которое оно возвращает.
Примите душ и ложитесь спать, а следующий раздел глубже
Уже поздно, поэтому я в конечном итоге напишу сегодня. Пока что каждый может придумать самое основное расширение Hello World C ++. В следующий раз, когда я напишу это, я не знаю, когда будет в следующий раз.
(Эй, эй, как мастер может быть таким безответственным! (O ゚ロ?) ┌┛σ (ノ ´ω`) ノ