Node-API
Node-API (ранее N-API) — это API для создания нативных аддонов. Он не зависит от базовой среды выполнения JavaScript (например, V8) и поддерживается в рамках самого Node.js. Этот API будет сохранять стабильность двоичного интерфейса приложений (ABI) в разных версиях Node.js. Он предназначен для защиты аддонов от изменений в базовом движке JavaScript и позволяет модулям, скомпилированным для одной основной версии, работать в более поздних основных версиях Node.js без повторной компиляции. Более подробное объяснение приведено в руководстве по стабильности ABI.
Аддоны собираются и упаковываются с помощью тех же подходов и инструментов, которые описаны в разделе Аддоны C++. Отличается только набор API, используемых нативным кодом. Вместо API V8 или Native Abstractions for Node.js используются функции, доступные в Node-API.
API, предоставляемые Node-API, обычно используются для создания значений JavaScript и управления ими. Понятия и операции, как правило, соответствуют концепциям, определенным в спецификации языка ECMA-262. API обладают следующими свойствами:
- Все вызовы Node-API возвращают код состояния типа
napi_status. Этот код указывает, успешно ли выполнен вызов API. - Возвращаемое значение API передается через выходной параметр.
- Все значения JavaScript скрыты за непрозрачным типом с именем
napi_value. - При коде состояния, указывающем на ошибку, дополнительную информацию можно получить с помощью
napi_get_last_error_info. Дополнительные сведения приведены в разделе об обработке ошибок Обработка ошибок.
Написание аддонов на различных языках программирования
Node-API — это C API, обеспечивающий стабильность ABI в разных версиях Node.js и на разных уровнях компиляторов. Эта гарантия стабильности позволяет писать аддоны на других языках программирования поверх Node-API. Дополнительные сведения о поддержке языков программирования и движков см. в разделе привязки языков и движков.
node-addon-api — это официальная привязка C++, обеспечивающая более эффективный способ написания кода C++, вызывающего Node-API. Эта обертка представляет собой библиотеку, состоящую только из заголовочных файлов, которая предоставляет встраиваемый API C++. Двоичные файлы, собранные с помощью node-addon-api, зависят от символов функций Node-API на основе C, экспортируемых Node.js. Следующий фрагмент кода представляет собой пример node-addon-api:
Object obj = Object::New(env); obj["foo"] = String::New(env, "bar"); copy
Приведенный выше код C++ node-addon-api эквивалентен следующему коду Node-API на основе C:
napi_status status;
napi_value object, string;
status = napi_create_object(env, &object);
if (status != napi_ok) {
napi_throw_error(env, ...);
return;
}
status = napi_create_string_utf8(env, "bar", NAPI_AUTO_LENGTH, &string);
if (status != napi_ok) {
napi_throw_error(env, ...);
return;
}
status = napi_set_named_property(env, object, "foo", string);
if (status != napi_ok) {
napi_throw_error(env, ...);
return;
} copy В результате аддон использует только экспортируемые API C. Несмотря на то что аддон написан на C++, он по-прежнему получает преимущества стабильности ABI, обеспечиваемой Node-API на C.
При использовании node-addon-api вместо API C начните с документации API для node-addon-api.
Ресурс Node-API — отличное руководство с советами для разработчиков, которые только начинают знакомиться с Node-API и node-addon-api. Дополнительные материалы доступны на странице Медиа-ресурсы Node-API.
Последствия стабильности ABI
Хотя Node-API гарантирует стабильность ABI, другие части Node.js такой гарантии не предоставляют, и она также может отсутствовать у любых внешних библиотек, используемых аддоном. В частности, для перечисленных ниже API не гарантируется стабильность ABI в разных основных версиях:
-
API C++ Node.js, доступные через любой из следующих интерфейсов
#include <node.h> #include <node_buffer.h> #include <node_version.h> #include <node_object_wrap.h> copy
-
API libuv, которые также входят в состав Node.js и доступны через
#include <uv.h> copy
-
API V8, доступный через
#include <v8.h> copy
Таким образом, чтобы аддон сохранял совместимость ABI в разных основных версиях Node.js, он должен использовать исключительно Node-API, ограничивая себя использованием
#include <node_api.h> copy
и проверяя, что для всех используемых внешних библиотек гарантируется стабильность ABI, аналогичная гарантиям Node-API.
Значения перечислений при стабильности ABI
Все типы данных перечислений, определенные в Node-API, следует считать значениями int32_t фиксированного размера. Типы перечислений с битовыми флагами должны быть явно задокументированы; они работают с побитовыми операторами, например побитовым ИЛИ (|), как с битовым значением. Если не указано иное, тип перечисления следует считать расширяемым.
Новое значение перечисления будет добавлено в конец его определения. Значения перечислений не удаляются и не переименовываются.
Для типа перечисления, возвращаемого функцией Node-API или предоставляемого в качестве выходного параметра функции Node-API, значение является целым числом, и аддон должен обрабатывать неизвестные значения. Новые значения могут вводиться без проверки версии. Например, при проверке napi_status в операторах switch аддон должен содержать ветвь по умолчанию, поскольку в новых версиях Node.js могут появиться новые коды состояния.
Для типа перечисления, используемого во входном параметре, результат передачи неизвестного целочисленного значения функциям Node-API не определен, если не указано иное. Новое значение добавляется с проверкой версии, указывающей версию Node-API, в которой оно появилось. Например, napi_get_all_property_names можно расширить новым значением перечисления napi_key_filter.
Для типа перечисления, используемого как во входных, так и в выходных параметрах, новые значения могут вводиться без проверки версии.
Сборка
В отличие от модулей, написанных на JavaScript, для разработки и развертывания нативных аддонов Node.js с помощью Node-API требуется дополнительный набор инструментов. Помимо основных инструментов, необходимых для разработки под Node.js, разработчику нативного аддона требуется цепочка инструментов, способная компилировать код C и C++ в двоичный файл. Кроме того, в зависимости от способа развертывания нативного аддона, пользователю нативного аддона также потребуется установленная цепочка инструментов C/C++.
Разработчикам Linux необходимые пакеты цепочки инструментов C/C++ доступны без труда. GCC широко используется в сообществе Node.js для сборки и тестирования на различных платформах. Для многих разработчиков хорошим выбором также является инфраструктура компилятора LLVM.
Разработчикам Mac все необходимые инструменты компиляции доступны в Xcode. Однако устанавливать всю интегрированную среду разработки Xcode необязательно. Следующая команда установит необходимую цепочку инструментов:
xcode-select --install copy
Разработчикам Windows все необходимые инструменты компиляции доступны в Visual Studio. Однако устанавливать всю интегрированную среду разработки Visual Studio необязательно. Следующая команда установит необходимую цепочку инструментов:
npm install --global windows-build-tools copy
В следующих разделах описаны дополнительные инструменты для разработки и развертывания нативных аддонов Node.js.
Инструменты сборки
Для успешной установки нативного аддона с помощью любого из перечисленных здесь инструментов пользователям необходимо установить цепочку инструментов C/C++.
node-gyp
node-gyp — это система сборки на основе форка gyp-next инструмента Google GYP, которая поставляется вместе с npm. Для работы GYP, а следовательно, и node-gyp, необходимо установить Python.
Исторически node-gyp был предпочтительным инструментом для сборки нативных аддонов. Он широко используется и хорошо документирован. Однако некоторые разработчики сталкивались с ограничениями node-gyp.
CMake.js
CMake.js — это альтернативная система сборки на основе CMake.
CMake.js — хороший выбор для проектов, уже использующих CMake, или для разработчиков, которых затрагивают ограничения node-gyp. build_with_cmake — пример проекта нативного аддона на основе CMake.
Загрузка предварительно скомпилированных двоичных файлов
Три перечисленных здесь инструмента позволяют разработчикам и сопровождающим нативных аддонов создавать двоичные файлы и загружать их на общедоступные или частные серверы. Обычно эти инструменты интегрируются с системами сборки CI/CD, такими как Travis CI и AppVeyor, для сборки и загрузки двоичных файлов для различных платформ и архитектур. Затем эти двоичные файлы становятся доступными для скачивания пользователям, которым не требуется устанавливать цепочку инструментов C/C++.
node-pre-gyp
node-pre-gyp — это инструмент на основе node-gyp, позволяющий загружать двоичные файлы на выбранный разработчиком сервер. node-pre-gyp особенно хорошо поддерживает загрузку двоичных файлов в Amazon S3.
prebuild
prebuild — это инструмент, поддерживающий сборку с помощью node-gyp или CMake.js. В отличие от node-pre-gyp, поддерживающего различные серверы, prebuild загружает двоичные файлы только в релизы GitHub. prebuild — хороший выбор для проектов на GitHub, использующих CMake.js.
prebuildify
prebuildify — это инструмент на основе node-gyp. Преимущество prebuildify заключается в том, что при загрузке нативного аддона в npm собранные двоичные файлы упаковываются вместе с ним. Двоичные файлы скачиваются из npm и сразу становятся доступны пользователю модуля после установки нативного аддона.
Использование
Чтобы использовать функции Node-API, включите файл node_api.h, расположенный в каталоге src дерева разработки node:
#include <node_api.h> copy
Это позволит использовать версию NAPI_VERSION по умолчанию для данного выпуска Node.js. Чтобы обеспечить совместимость с определенными версиями Node-API, можно явно указать версию при включении заголовочного файла:
#define NAPI_VERSION 3 #include <node_api.h> copy
Это ограничивает доступную поверхность Node-API функциональностью, доступной в указанной версии и более ранних версиях.
Некоторые возможности Node-API являются экспериментальными и требуют явного разрешения на использование:
#define NAPI_EXPERIMENTAL #include <node_api.h> copy
В этом случае коду модуля будет доступна вся поверхность API, включая экспериментальные API.
Иногда вводятся экспериментальные функции, влияющие на уже выпущенные стабильные API. Эти функции можно отключить с помощью параметра, запрещающего их использование:
#define NAPI_EXPERIMENTAL #define NODE_API_EXPERIMENTAL_<FEATURE_NAME>_OPT_OUT #include <node_api.h> copy
где <FEATURE_NAME> — имя экспериментальной функции, влияющей как на экспериментальные, так и на стабильные API.
Матрица версий Node-API
До версии 9 версии Node-API расширялись и нумеровались независимо от Node.js. Это означало, что каждая версия была расширением предыдущей: она включала все API предыдущей версии и некоторые дополнения. Каждая версия Node.js поддерживала только одну версию Node-API. Например, v18.15.0 поддерживает только версию 8 Node-API. Стабильность ABI обеспечивалась тем, что версия 8 строго включала в себя все предыдущие версии.
Начиная с версии 9, версии Node-API по-прежнему нумеруются независимо, однако для работы аддона, использующего Node-API версии 9, с Node-API версии 10 могут потребоваться изменения в коде. При этом стабильность ABI сохраняется: версии Node.js, поддерживающие версии Node-API выше 8, будут поддерживать все версии от 8 до самой высокой поддерживаемой версии и по умолчанию предоставлять API версии 8, если аддон не запросит более высокую версию Node-API. Такой подход обеспечивает гибкость для более эффективной оптимизации существующих функций Node-API при сохранении стабильности ABI. Существующие аддоны могут продолжать работать без повторной компиляции с использованием более ранней версии Node-API. Если аддону требуются возможности более новой версии Node-API, для использования новых функций все равно потребуются изменения существующего кода и его повторная компиляция.
В версиях Node.js, поддерживающих Node-API версии 9 и более поздние, определение NAPI_VERSION=X и использование существующих макросов инициализации аддона встраивают в аддон запрошенную версию Node-API, которая будет использоваться во время выполнения. Если NAPI_VERSION не задан, по умолчанию используется версия 8.
В старых ветках эта таблица может быть неактуальной. Самая актуальная информация приведена в последней версии документации API: Матрица версий Node-API
| Версия Node-API | Поддерживается в |
|---|---|
| 10 | v22.14.0+, 23.6.0+ и всех более поздних версиях |
| 9 | v18.17.0+, 20.3.0+, 21.0.0 и всех более поздних версиях |
| 8 | v12.22.0+, v14.17.0+, v15.12.0+, 16.0.0 и всех более поздних версиях |
| 7 | v10.23.0+, v12.19.0+, v14.12.0+, 15.0.0 и всех более поздних версиях |
| 6 | v10.20.0+, v12.17.0+, 14.0.0 и всех более поздних версиях |
| 5 | v10.17.0+, v12.11.0+, 13.0.0 и всех более поздних версиях |
| 4 | v10.16.0+, v11.8.0+, 12.0.0 и всех более поздних версиях |
| 3 | v6.14.2*, 8.11.2+, v9.11.0+*, 10.0.0 и всех более поздних версиях |
| 2 | v8.10.0+*, v9.3.0+*, 10.0.0 и всех более поздних версиях |
| 1 | v8.6.0+**, v9.0.0+*, 10.0.0 и всех более поздних версиях |
* Node-API был экспериментальным.
** В Node.js 8.0.0 Node-API был представлен как экспериментальный. Он был выпущен как Node-API версии 1, но продолжал развиваться до Node.js 8.6.0. В версиях до Node.js 8.6.0 API отличается. Мы рекомендуем Node-API версии 3 или более поздней.
Для каждого API, описанного в документации Node-API, указан заголовок added in:, а для стабильных API — дополнительный заголовок Node-API version:. API можно использовать напрямую в версиях Node.js, поддерживающих версию Node-API, указанную в Node-API version: или выше. Если используется версия Node.js, не поддерживающая указанную в Node-API version: версию, или если Node-API version: отсутствует, API будет доступен только в том случае, если перед включением node_api.h или js_native_api.h указан #define NAPI_EXPERIMENTAL. Если API, по всей видимости, недоступен в версии Node.js, более поздней, чем версия, указанная в added in:, скорее всего, причина кажущегося отсутствия именно в этом.
API Node-API, предназначенные исключительно для доступа к функциям ECMAScript из нативного кода, описаны отдельно в js_native_api.h и js_native_api_types.h. API, определенные в этих заголовочных файлах, включены в node_api.h и node_api_types.h. Такая структура заголовочных файлов позволяет реализовывать Node-API за пределами Node.js. В таких реализациях API, специфичные для Node.js, могут быть неприменимы.
Специфичные для Node.js части аддона можно отделить от кода, предоставляющего фактическую функциональность среде JavaScript, чтобы последний можно было использовать с несколькими реализациями Node-API. В приведенном ниже примере addon.c и addon.h относятся только к js_native_api.h. Это гарантирует, что addon.c можно повторно использовать для сборки как с реализацией Node-API в Node.js, так и с любой реализацией Node-API за пределами Node.js.
addon_node.c — это отдельный файл, содержащий специфичную для Node.js точку входа аддона. Он создает экземпляр аддона, вызывая addon.c при загрузке аддона в среду Node.js.
// addon.h #ifndef _ADDON_H_ #define _ADDON_H_ #include <js_native_api.h> napi_value create_addon(napi_env env); #endif // _ADDON_H_ copy
// addon.c
#include "addon.h"
#define NODE_API_CALL(env, call) \
do { \
napi_status status = (call); \
if (status != napi_ok) { \
const napi_extended_error_info* error_info = NULL; \
napi_get_last_error_info((env), &error_info); \
const char* err_message = error_info->error_message; \
bool is_pending; \
napi_is_exception_pending((env), &is_pending); \
/* If an exception is already pending, don't rethrow it */ \
if (!is_pending) { \
const char* message = (err_message == NULL) \
? "empty error message" \
: err_message; \
napi_throw_error((env), NULL, message); \
} \
return NULL; \
} \
} while(0)
static napi_value
DoSomethingUseful(napi_env env, napi_callback_info info) {
// Do something useful.
return NULL;
}
napi_value create_addon(napi_env env) {
napi_value result;
NODE_API_CALL(env, napi_create_object(env, &result));
napi_value exported_function;
NODE_API_CALL(env, napi_create_function(env,
"doSomethingUseful",
NAPI_AUTO_LENGTH,
DoSomethingUseful,
NULL,
&exported_function));
NODE_API_CALL(env, napi_set_named_property(env,
result,
"doSomethingUseful",
exported_function));
return result;
} copy // addon_node.c
#include <node_api.h>
#include "addon.h"
NAPI_MODULE_INIT(/* napi_env env, napi_value exports */) {
// This function body is expected to return a `napi_value`.
// The variables `napi_env env` and `napi_value exports` may be used within
// the body, as they are provided by the definition of `NAPI_MODULE_INIT()`.
return create_addon(env);
} copy API жизненного цикла среды
Раздел «Агенты» спецификации языка ECMAScript определяет понятие «агент» как автономную среду, в которой выполняется код JavaScript. Несколько таких агентов могут запускаться и завершаться процессом одновременно или последовательно.
Среда Node.js соответствует агенту ECMAScript. В основном процессе среда создается при запуске, а дополнительные среды могут создаваться в отдельных потоках для работы в качестве рабочих потоков. Когда Node.js встроен в другое приложение, основной поток приложения также может многократно создавать и уничтожать среду Node.js в течение жизненного цикла процесса приложения. При этом каждая созданная приложением среда Node.js, в свою очередь, может в течение своего жизненного цикла создавать и уничтожать дополнительные среды в качестве рабочих потоков.
Для нативного аддона это означает, что предоставляемые им привязки могут вызываться несколько раз, из разных контекстов и даже одновременно из нескольких потоков.
Нативным аддонам может потребоваться выделять глобальное состояние, используемое ими в течение жизненного цикла среды Node.js, причем это состояние должно быть уникальным для каждого экземпляра аддона.
Для этого Node-API предоставляет способ связывать данные так, чтобы их жизненный цикл был связан с жизненным циклом среды Node.js.
napi_set_instance_data
napi_status napi_set_instance_data(node_api_basic_env env,
void* data,
napi_finalize finalize_cb,
void* finalize_hint); copy -
[in] env: Среда, в которой вызывается Node-API. -
[in] data: Элемент данных, который нужно сделать доступным для привязок этого экземпляра. -
[in] finalize_cb: Функция, вызываемая при завершении работы среды. Функция получаетdata, чтобы освободить его. Дополнительные сведения приведены в разделеnapi_finalize. -
[in] finalize_hint: Необязательная подсказка, передаваемая функции обратного вызова финализации во время сборки мусора.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API связывает data с текущей работающей средой Node.js. Позднее data можно получить с помощью napi_get_instance_data(). Любые существующие данные, связанные с текущей работающей средой Node.js посредством предыдущего вызова napi_set_instance_data(), будут перезаписаны. Если при предыдущем вызове был указан finalize_cb, он не будет вызван.
napi_get_instance_data
napi_status napi_get_instance_data(node_api_basic_env env,
void** data); copy -
[in] env: Среда, в которой вызывается Node-API. -
[out] data: Элемент данных, ранее связанный с текущей работающей средой Node.js вызовомnapi_set_instance_data().
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API извлекает данные, ранее связанные с текущей работающей средой Node.js с помощью napi_set_instance_data(). Если данные не заданы, вызов завершится успешно, а data будет установлено в NULL.
Основные типы данных Node-API
Node-API предоставляет следующие фундаментальные типы данных в виде абстракций, используемых различными API. Эти API следует считать непрозрачными; исследовать их можно только с помощью других вызовов Node-API.
napi_status
Целочисленный код состояния, указывающий на успешное выполнение или сбой вызова Node-API. В настоящее время поддерживаются следующие коды состояния.
typedef enum {
napi_ok,
napi_invalid_arg,
napi_object_expected,
napi_string_expected,
napi_name_expected,
napi_function_expected,
napi_number_expected,
napi_boolean_expected,
napi_array_expected,
napi_generic_failure,
napi_pending_exception,
napi_cancelled,
napi_escape_called_twice,
napi_handle_scope_mismatch,
napi_callback_scope_mismatch,
napi_queue_full,
napi_closing,
napi_bigint_expected,
napi_date_expected,
napi_arraybuffer_expected,
napi_detachable_arraybuffer_expected,
napi_would_deadlock, /* unused */
napi_no_external_buffers_allowed,
napi_cannot_run_js
} napi_status; copy Если после возврата API статуса ошибки требуется дополнительная информация, её можно получить вызовом napi_get_last_error_info.
napi_extended_error_info
typedef struct {
const char* error_message;
void* engine_reserved;
uint32_t engine_error_code;
napi_status error_code;
} napi_extended_error_info; copy -
error_message: строка в кодировке UTF-8, содержащая нейтральное по отношению к виртуальной машине описание ошибки. -
engine_reserved: зарезервировано для сведений об ошибке, специфичных для виртуальной машины. В настоящее время эта возможность не реализована ни для одной виртуальной машины. -
engine_error_code: код ошибки, специфичный для виртуальной машины. В настоящее время эта возможность не реализована ни для одной виртуальной машины. -
error_code: код состояния Node-API, соответствующий последней ошибке.
Дополнительные сведения см. в разделе Обработка ошибок.
napi_env
napi_env используется для представления контекста, который базовая реализация Node-API может применять для сохранения состояния, специфичного для виртуальной машины. Эта структура передаётся нативным функциям при их вызове и должна передаваться обратно при вызовах Node-API. В частности, при всех последующих вложенных вызовах Node-API необходимо передавать то же значение napi_env, которое было передано при первоначальном вызове нативной функции. Кэшировать napi_env для повторного использования в общем случае и передавать napi_env между экземплярами одного и того же дополнения, работающими в разных потоках Worker, запрещено. napi_env становится недействительным при выгрузке экземпляра нативного дополнения. Уведомление об этом событии отправляется через обратные вызовы, переданные в napi_add_env_cleanup_hook и napi_set_instance_data.
node_api_basic_env
Этот вариант napi_env передаётся синхронным финализаторам (node_api_basic_finalize). Существует подмножество API Node-API, принимающих параметр типа node_api_basic_env в качестве первого аргумента. Эти API не обращаются к состоянию движка JavaScript, поэтому их безопасно вызывать из синхронных финализаторов. Передавать этим API параметр типа napi_env разрешено, однако передавать параметр типа node_api_basic_env в API, обращающиеся к состоянию движка JavaScript, запрещено. Попытка сделать это без приведения типа приведёт к предупреждению компилятора или ошибке, если дополнения компилируются с флагами, вызывающими предупреждения и/или ошибки при передаче функции указателей неверных типов. Вызов таких API из синхронного финализатора в конечном итоге приведёт к завершению приложения.
napi_value
Это непрозрачный указатель, используемый для представления значения JavaScript.
napi_threadsafe_function
Это непрозрачный указатель, представляющий функцию JavaScript, которую можно асинхронно вызывать из нескольких потоков с помощью napi_call_threadsafe_function().
napi_threadsafe_function_release_mode
Значение, передаваемое в napi_release_threadsafe_function() и указывающее, следует ли немедленно закрыть потокобезопасную функцию (napi_tsfn_abort) или только освободить её (napi_tsfn_release), чтобы затем снова использовать с помощью napi_acquire_threadsafe_function() и napi_call_threadsafe_function().
typedef enum {
napi_tsfn_release,
napi_tsfn_abort
} napi_threadsafe_function_release_mode; copy
napi_threadsafe_function_call_mode
Значение, передаваемое в napi_call_threadsafe_function() и указывающее, должен ли вызов блокироваться при заполнении очереди, связанной с потокобезопасной функцией.
typedef enum {
napi_tsfn_nonblocking,
napi_tsfn_blocking
} napi_threadsafe_function_call_mode; copy Типы Node-API для управления памятью
napi_handle_scope
Эта абстракция позволяет контролировать и изменять время жизни объектов, созданных в определённой области видимости. Как правило, значения Node-API создаются в контексте области видимости дескрипторов. При вызове нативного метода из JavaScript существует область видимости дескрипторов по умолчанию. Если пользователь явно не создаёт новую область видимости дескрипторов, значения Node-API создаются в области видимости по умолчанию. При любом выполнении кода вне вызова нативного метода (например, во время вызова обратного вызова libuv) модуль должен создать область видимости до вызова любых функций, которые могут привести к созданию значений JavaScript.
Области видимости дескрипторов создаются с помощью napi_open_handle_scope и уничтожаются с помощью napi_close_handle_scope. Закрытие области видимости может сообщить сборщику мусора, что все napi_value, созданные за время существования этой области, больше не используются из текущего кадра стека.
Дополнительные сведения см. в разделе Управление временем жизни объектов.
napi_escapable_handle_scope
Области видимости дескрипторов с возможностью выхода — это особый тип областей видимости, позволяющий передавать значения, созданные в определённой области видимости дескрипторов, во внешнюю область.
napi_ref
Эта абстракция используется для создания ссылки на napi_value. Она позволяет управлять временем жизни значений JavaScript, в том числе явно задавать минимальное время их существования.
Дополнительные сведения см. в разделе Управление временем жизни объектов.
napi_type_tag
128-битное значение, хранящееся в виде двух беззнаковых 64-битных целых чисел. Оно служит UUID, которым можно «пометить» объекты JavaScript или внешние объекты, чтобы удостовериться, что они имеют определённый тип. Эта проверка надёжнее, чем napi_instanceof, поскольку последняя может дать ложноположительный результат, если прототип объекта был изменён. Пометка типа особенно полезна вместе с napi_wrap, поскольку она гарантирует, что указатель, полученный из обёрнутого объекта, можно безопасно привести к нативному типу, соответствующему тегу типа, ранее применённому к объекту JavaScript.
typedef struct {
uint64_t lower;
uint64_t upper;
} napi_type_tag; copy
napi_async_cleanup_hook_handle
Непрозрачное значение, возвращаемое napi_add_async_cleanup_hook. После завершения цепочки асинхронных событий очистки его необходимо передать в napi_remove_async_cleanup_hook.
Типы обратных вызовов Node-API
napi_callback_info
Непрозрачный тип данных, передаваемый функции обратного вызова. Его можно использовать для получения дополнительных сведений о контексте, в котором был вызван обратный вызов.
napi_callback
Тип указателя на функцию для предоставляемых пользователем нативных функций, которые должны быть доступны JavaScript через Node-API. Функции обратного вызова должны соответствовать следующей сигнатуре:
typedef napi_value (*napi_callback)(napi_env, napi_callback_info); copy
За исключением случаев, рассмотренных в разделе Управление временем жизни объектов, создавать область видимости дескрипторов и/или область видимости обратного вызова внутри napi_callback не требуется.
node_api_basic_finalize
Тип указателя на функцию, предоставляемую дополнением и позволяющую уведомить пользователя о том, что принадлежащие внешнему источнику данные готовы к очистке, поскольку связанный с ними объект был удалён сборщиком мусора. Пользователь должен предоставить функцию, соответствующую следующей сигнатуре; она будет вызвана при сборе объекта сборщиком мусора. В настоящее время node_api_basic_finalize можно использовать, чтобы определить, когда удаляются объекты, содержащие внешние данные.
typedef void (*node_api_basic_finalize)(node_api_basic_env env,
void* finalize_data,
void* finalize_hint); copy За исключением случаев, рассмотренных в разделе Управление временем жизни объектов, создавать область видимости дескрипторов и/или область видимости обратного вызова внутри тела функции не требуется.
Поскольку эти функции могут вызываться, когда движок JavaScript находится в состоянии, в котором он не может выполнять код JavaScript, разрешается вызывать только API Node-API, принимающие node_api_basic_env в качестве первого параметра. С помощью node_api_post_finalizer можно запланировать вызовы Node-API, которым требуется доступ к состоянию движка JavaScript, на момент после завершения текущего цикла сборки мусора.
В случае node_api_create_external_string_latin1 и node_api_create_external_string_utf16 параметр env может быть равен null, поскольку внешние строки могут быть удалены на заключительном этапе завершения работы среды.
История изменений:
-
экспериментальная возможность (
NAPI_EXPERIMENTAL):Разрешается вызывать только API Node-API, принимающие
node_api_basic_envв качестве первого параметра; в противном случае приложение будет завершено с соответствующим сообщением об ошибке. Эту возможность можно отключить, определивNODE_API_EXPERIMENTAL_BASIC_ENV_OPT_OUT.
napi_finalize
Тип указателя на функцию, предоставляемую дополнением и позволяющую пользователю запланировать группу вызовов API Node-API в ответ на событие сборки мусора после завершения цикла сборки мусора. Эти указатели на функции можно использовать с node_api_post_finalizer.
typedef void (*napi_finalize)(napi_env env,
void* finalize_data,
void* finalize_hint); copy История изменений:
-
экспериментальная возможность (определён
NAPI_EXPERIMENTAL):Функцию этого типа больше нельзя использовать как финализатор, кроме как с
node_api_post_finalizer. Вместо неё необходимо использоватьnode_api_basic_finalize. Эту возможность можно отключить, определивNODE_API_EXPERIMENTAL_BASIC_ENV_OPT_OUT.
napi_async_execute_callback
Тип указателя на функцию, используемый с функциями, поддерживающими асинхронные операции. Функции обратного вызова должны соответствовать следующей сигнатуре:
typedef void (*napi_async_execute_callback)(napi_env env, void* data); copy
Реализации этой функции не должны вызывать Node-API, выполняющие код JavaScript или взаимодействующие с объектами JavaScript. Вызовы Node-API следует выполнять в napi_async_complete_callback. Не используйте параметр napi_env, так как это, вероятно, приведёт к выполнению JavaScript.
napi_async_complete_callback
Тип указателя на функцию, используемый с функциями, поддерживающими асинхронные операции. Функции обратного вызова должны соответствовать следующей сигнатуре:
typedef void (*napi_async_complete_callback)(napi_env env,
napi_status status,
void* data); copy За исключением случаев, рассмотренных в разделе Управление временем жизни объектов, создавать область видимости дескрипторов и/или область видимости обратного вызова внутри тела функции не требуется.
napi_threadsafe_function_call_js
Тип указателя на функцию, используемый при асинхронных вызовах потокобезопасных функций. Обратный вызов выполняется в главном потоке. Его задача — использовать элемент данных, поступивший через очередь из одного из дополнительных потоков, сформировать параметры, необходимые для вызова JavaScript (обычно с помощью napi_call_function), а затем выполнить вызов JavaScript.
Данные, поступившие из дополнительного потока через очередь, передаются в параметре data, а вызываемая функция JavaScript — в параметре js_callback.
Перед вызовом этого обратного вызова Node-API настраивает среду, поэтому достаточно вызвать функцию JavaScript с помощью napi_call_function, а не napi_make_callback.
Функции обратного вызова должны соответствовать следующей сигнатуре:
typedef void (*napi_threadsafe_function_call_js)(napi_env env,
napi_value js_callback,
void* context,
void* data); copy -
[in] env: среда, используемая для вызовов API, илиNULL, если потокобезопасная функция завершает работу и может потребоваться освободитьdata. -
[in] js_callback: вызываемая функция JavaScript илиNULL, если потокобезопасная функция завершает работу и может потребоваться освободитьdata. Также может быть равноNULL, если потокобезопасная функция была создана безjs_callback. -
[in] context: необязательные данные, с которыми была создана потокобезопасная функция. -
[in] data: данные, созданные дополнительным потоком. Обратный вызов должен преобразовать эти нативные данные в значения JavaScript (с помощью функций Node-API), которые можно передать в качестве параметров при вызовеjs_callback. Управление этим указателем полностью осуществляется потоками и данным обратным вызовом. Поэтому обратный вызов должен освободить данные.
За исключением случаев, рассмотренных в разделе Управление временем жизни объектов, создавать область видимости дескрипторов и/или область видимости обратного вызова внутри тела функции не требуется.
napi_cleanup_hook
Тип указателя на функцию, используемый с napi_add_env_cleanup_hook. Функция будет вызвана при завершении работы среды.
Функции обратного вызова должны соответствовать следующей сигнатуре:
typedef void (*napi_cleanup_hook)(void* data); copy
-
[in] data: данные, переданные вnapi_add_env_cleanup_hook.
napi_async_cleanup_hook
Тип указателя на функцию, используемый с napi_add_async_cleanup_hook. Функция будет вызвана при завершении работы среды.
Функции обратного вызова должны соответствовать следующей сигнатуре:
typedef void (*napi_async_cleanup_hook)(napi_async_cleanup_hook_handle handle,
void* data); copy -
[in] handle: дескриптор, который после завершения асинхронной очистки необходимо передать вnapi_remove_async_cleanup_hook. -
[in] data: данные, переданные вnapi_add_async_cleanup_hook.
Тело функции должно запускать действия по асинхронной очистке, по завершении которых handle необходимо передать при вызове napi_remove_async_cleanup_hook.
Обработка ошибок
Node-API использует для обработки ошибок как возвращаемые значения, так и исключения JavaScript. В следующих разделах описан подход для каждого случая.
Возвращаемые значения
Для всех функций Node-API используется один и тот же шаблон обработки ошибок. Тип возвращаемого значения всех функций API — napi_status.
Возвращаемым значением будет napi_ok, если запрос выполнен успешно и не было выброшено необработанное исключение JavaScript. Если произошла ошибка И было выброшено исключение, будет возвращено значение napi_status, соответствующее этой ошибке. Если было выброшено исключение, но ошибки не произошло, будет возвращено napi_pending_exception.
Если возвращено значение, отличное от napi_ok или napi_pending_exception, необходимо вызвать napi_is_exception_pending, чтобы проверить, ожидает ли обработки исключение. Подробнее см. раздел об исключениях.
Полный набор возможных значений napi_status определён в napi_api_types.h.
Возвращаемое значение napi_status обеспечивает независимое от виртуальной машины представление произошедшей ошибки. В некоторых случаях полезно получить более подробную информацию, в том числе строку с описанием ошибки и сведения, специфичные для виртуальной машины (движка).
Для получения этой информации предусмотрена функция napi_get_last_error_info, которая возвращает структуру napi_extended_error_info. Формат структуры napi_extended_error_info выглядит следующим образом:
typedef struct napi_extended_error_info {
const char* error_message;
void* engine_reserved;
uint32_t engine_error_code;
napi_status error_code;
}; copy -
error_message: Текстовое описание произошедшей ошибки. -
engine_reserved: Непрозрачный дескриптор, зарезервированный только для использования движком. -
engine_error_code: Код ошибки, специфичный для виртуальной машины. -
error_code: Код состояния Node-API для последней ошибки.
napi_get_last_error_info возвращает сведения о последнем вызове Node-API.
Не полагайтесь на содержимое или формат каких-либо дополнительных сведений: они не подпадают под действие SemVer и могут измениться в любой момент. Эти сведения предназначены только для ведения журналов.
napi_get_last_error_info
napi_status
napi_get_last_error_info(node_api_basic_env env,
const napi_extended_error_info** result); copy -
[in] env: Среда, в которой вызывается API. -
[out] result: Структураnapi_extended_error_infoс дополнительными сведениями об ошибке.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API получает структуру napi_extended_error_info со сведениями о последней произошедшей ошибке.
Содержимое возвращённой структуры napi_extended_error_info действительно только до тех пор, пока для той же env не будет вызвана функция Node-API. Это относится и к вызову napi_is_exception_pending, поэтому часто необходимо скопировать сведения, чтобы использовать их позднее. Указатель, возвращаемый в error_message, указывает на статически определённую строку, поэтому его безопасно использовать, если до вызова другой функции Node-API вы скопировали её из поля error_message (которое будет перезаписано).
Не полагайтесь на содержимое или формат каких-либо дополнительных сведений: они не подпадают под действие SemVer и могут измениться в любой момент. Эти сведения предназначены только для ведения журналов.
Этот API можно вызвать, даже если ожидает обработки исключение JavaScript.
Исключения
Вызов любой функции Node-API может привести к появлению ожидающего обработки исключения JavaScript. Это относится ко всем функциям API, в том числе к тем, которые не могут привести к выполнению кода JavaScript.
Если функция возвращает napi_status со значением napi_ok, исключение не ожидает обработки и никаких дополнительных действий не требуется. Если возвращённое значение napi_status не равно napi_ok или napi_pending_exception, необходимо вызвать napi_is_exception_pending, чтобы определить, ожидает ли обработки исключение, и попытаться восстановить работу и продолжить выполнение, а не просто немедленно вернуть управление.
Во многих случаях при вызове функции Node-API, когда уже ожидает обработки исключение, функция немедленно возвращает значение napi_status, равное napi_pending_exception. Однако так происходит не со всеми функциями. Node-API позволяет вызывать некоторые функции, чтобы выполнить минимальную очистку перед возвратом в JavaScript. В этом случае napi_status будет отражать состояние функции, но не предыдущие ожидающие обработки исключения. Чтобы избежать путаницы, проверяйте статус ошибки после каждого вызова функции.
При ожидающем обработки исключении можно использовать один из двух подходов.
Первый подход — выполнить необходимые действия по очистке и затем вернуть управление, чтобы выполнение продолжилось в JavaScript. При переходе обратно в JavaScript исключение будет выброшено в той точке кода JavaScript, где был вызван нативный метод. Поведение большинства вызовов Node-API при ожидающем обработки исключении не определено, и многие из них просто вернут napi_pending_exception, поэтому выполните как можно меньше действий и вернитесь в JavaScript, где исключение можно обработать.
Второй подход — попытаться обработать исключение. В некоторых случаях нативный код может перехватить исключение, выполнить необходимые действия и продолжить работу. Это рекомендуется только в отдельных случаях, когда известно, что исключение можно безопасно обработать. В таких случаях для получения и очистки исключения можно использовать napi_get_and_clear_last_exception. При успешном выполнении результат будет содержать дескриптор последнего выброшенного значения JavaScript Object. Если после получения исключения выяснится, что обработать его всё-таки нельзя, его можно выбросить повторно с помощью napi_throw, где error — это значение JavaScript, которое нужно выбросить.
Также доступны следующие вспомогательные функции на случай, если нативному коду необходимо выбросить исключение или определить, является ли napi_value экземпляром объекта JavaScript Error: napi_throw_error, napi_throw_type_error, napi_throw_range_error, node_api_throw_syntax_error и napi_is_error.
Также доступны следующие вспомогательные функции на случай, если нативному коду необходимо создать объект Error: napi_create_error, napi_create_type_error, napi_create_range_error и node_api_create_syntax_error, где result — это napi_value, ссылающийся на вновь созданный объект JavaScript Error.
Проект Node.js добавляет к ошибкам, генерируемым внутри системы, коды ошибок. Цель состоит в том, чтобы приложения использовали эти коды при проверке ошибок. Связанные с ними сообщения об ошибках сохранятся, но будут предназначены только для журналов и отображения, поскольку сообщения могут изменяться без применения SemVer. Чтобы поддержать эту модель в Node-API как для встроенных функций, так и для функций конкретных модулей (что является хорошей практикой), функции throw_ и create_ принимают необязательный параметр code — строку с кодом, который будет добавлен к объекту ошибки. Если необязательный параметр равен NULL, код не будет связан с ошибкой. Если код указан, имя ошибки также обновляется и принимает следующий вид:
originalName [code] copy
где originalName — исходное имя ошибки, а code — указанный код. Например, если код равен 'ERR_ERROR_1' и создаётся TypeError, имя будет следующим:
TypeError [ERR_ERROR_1] copy
napi_throw
NAPI_EXTERN napi_status napi_throw(napi_env env, napi_value error); copy
-
[in] env: Среда, в которой вызывается API. -
[in] error: Значение JavaScript, которое нужно выбросить.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API выбрасывает указанное значение JavaScript.
napi_throw_error
NAPI_EXTERN napi_status napi_throw_error(napi_env env,
const char* code,
const char* msg); copy -
[in] env: Среда, в которой вызывается API. -
[in] code: Необязательный код ошибки, который будет задан для ошибки. -
[in] msg: Строка C с текстом, который будет связан с ошибкой.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API выбрасывает ошибку JavaScript Error с указанным текстом.
napi_throw_type_error
NAPI_EXTERN napi_status napi_throw_type_error(napi_env env,
const char* code,
const char* msg); copy -
[in] env: Среда, в которой вызывается API. -
[in] code: Необязательный код ошибки, который будет задан для ошибки. -
[in] msg: Строка C с текстом, который будет связан с ошибкой.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API выбрасывает ошибку JavaScript TypeError с указанным текстом.
napi_throw_range_error
NAPI_EXTERN napi_status napi_throw_range_error(napi_env env,
const char* code,
const char* msg); copy -
[in] env: Среда, в которой вызывается API. -
[in] code: Необязательный код ошибки, который будет задан для ошибки. -
[in] msg: Строка C с текстом, который будет связан с ошибкой.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API выбрасывает ошибку JavaScript RangeError с указанным текстом.
node_api_throw_syntax_error
NAPI_EXTERN napi_status node_api_throw_syntax_error(napi_env env,
const char* code,
const char* msg); copy -
[in] env: Среда, в которой вызывается API. -
[in] code: Необязательный код ошибки, который будет задан для ошибки. -
[in] msg: Строка C с текстом, который будет связан с ошибкой.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API выбрасывает ошибку JavaScript SyntaxError с указанным текстом.
napi_is_error
NAPI_EXTERN napi_status napi_is_error(napi_env env,
napi_value value,
bool* result); copy -
[in] env: Среда, в которой вызывается API. -
[in] value: Проверяемыйnapi_value. -
[out] result: Логическое значение, которому присваивается true, еслиnapi_valueпредставляет ошибку, и false в противном случае.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API проверяет napi_value, чтобы определить, представляет ли он объект ошибки.
napi_create_error
NAPI_EXTERN napi_status napi_create_error(napi_env env,
napi_value code,
napi_value msg,
napi_value* result); copy -
[in] env: Среда, в которой вызывается API. -
[in] code: Необязательныйnapi_valueсо строкой кода ошибки, которая будет связана с ошибкой. -
[in] msg:napi_value, ссылающийся на объект JavaScriptstring, который будет использоваться в качестве сообщения дляError. -
[out] result:napi_value, представляющий созданную ошибку.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API возвращает ошибку JavaScript Error с указанным текстом.
napi_create_type_error
NAPI_EXTERN napi_status napi_create_type_error(napi_env env,
napi_value code,
napi_value msg,
napi_value* result); copy -
[in] env: Среда, в которой вызывается API. -
[in] code: Необязательныйnapi_valueсо строкой кода ошибки, которая будет связана с ошибкой. -
[in] msg:napi_value, ссылающийся на объект JavaScriptstring, который будет использоваться в качестве сообщения дляError. -
[out] result:napi_value, представляющий созданную ошибку.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API возвращает ошибку JavaScript TypeError с указанным текстом.
napi_create_range_error
NAPI_EXTERN napi_status napi_create_range_error(napi_env env,
napi_value code,
napi_value msg,
napi_value* result); copy -
[in] env: Среда, в которой вызывается API. -
[in] code: Необязательныйnapi_valueсо строкой кода ошибки, которая будет связана с ошибкой. -
[in] msg:napi_value, ссылающийся на объект JavaScriptstring, который будет использоваться в качестве сообщения дляError. -
[out] result:napi_value, представляющий созданную ошибку.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API возвращает ошибку JavaScript RangeError с указанным текстом.
node_api_create_syntax_error
NAPI_EXTERN napi_status node_api_create_syntax_error(napi_env env,
napi_value code,
napi_value msg,
napi_value* result); copy -
[in] env: Среда, в которой вызывается API. -
[in] code: Необязательныйnapi_valueсо строкой кода ошибки, которая будет связана с ошибкой. -
[in] msg:napi_value, ссылающийся на объект JavaScriptstring, который будет использоваться в качестве сообщения дляError. -
[out] result:napi_value, представляющий созданную ошибку.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API возвращает ошибку JavaScript SyntaxError с указанным текстом.
napi_get_and_clear_last_exception
napi_status napi_get_and_clear_last_exception(napi_env env,
napi_value* result); copy -
[in] env: Среда, в которой вызывается API. -
[out] result: Исключение, если оно ожидает обработки; в противном случае —NULL.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API можно вызвать, даже если ожидает обработки исключение JavaScript.
napi_is_exception_pending
napi_status napi_is_exception_pending(napi_env env, bool* result); copy
-
[in] env: Среда, в которой вызывается API. -
[out] result: Логическое значение, которому присваивается true, если ожидает обработки исключение.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API можно вызвать, даже если ожидает обработки исключение JavaScript.
napi_fatal_exception
napi_status napi_fatal_exception(napi_env env, napi_value err); copy
-
[in] env: Среда, в которой вызывается API. -
[in] err: Ошибка, передаваемая в'uncaughtException'.
Вызывает 'uncaughtException' в JavaScript. Полезно, если асинхронный обратный вызов выбрасывает исключение, которое невозможно обработать.
Критические ошибки
В случае неустранимой ошибки в нативном дополнении можно выбросить критическую ошибку, чтобы немедленно завершить процесс.
napi_fatal_error
NAPI_NO_RETURN void napi_fatal_error(const char* location,
size_t location_len,
const char* message,
size_t message_len); copy -
[in] location: Необязательное место, в котором произошла ошибка. -
[in] location_len: Длина места в байтах илиNAPI_AUTO_LENGTH, если строка завершается нулевым символом. -
[in] message: Сообщение, связанное с ошибкой. -
[in] message_len: Длина сообщения в байтах илиNAPI_AUTO_LENGTH, если строка завершается нулевым символом.
Вызов функции не возвращает управление; процесс будет завершён.
Этот API можно вызвать, даже если ожидает обработки исключение JavaScript.
Управление временем жизни объектов
При выполнении вызовов Node-API могут возвращаться дескрипторы объектов в куче базовой виртуальной машины в виде napi_values. Эти дескрипторы должны удерживать объекты «живыми», пока они не перестанут быть нужны нативному коду, иначе объекты могут быть собраны до того, как нативный код завершит работу с ними.
Возвращаемые дескрипторы объектов связываются с «областью». Время жизни области по умолчанию связано со временем жизни вызова нативного метода. В результате по умолчанию дескрипторы остаются действительными, а связанные с ними объекты удерживаются живыми в течение всего времени вызова нативного метода.
Однако во многих случаях необходимо, чтобы дескрипторы оставались действительными меньшее или большее время, чем нативный метод. В следующих разделах описаны функции Node-API, позволяющие изменить время жизни дескрипторов по умолчанию.
Сокращение времени жизни дескриптора по сравнению со временем жизни нативного метода
Часто необходимо, чтобы время жизни дескрипторов было короче времени жизни нативного метода. Например, рассмотрим нативный метод, содержащий цикл, который перебирает элементы большого массива:
for (int i = 0; i < 1000000; i++) {
napi_value result;
napi_status status = napi_get_element(env, object, i, &result);
if (status != napi_ok) {
break;
}
// do something with element
} copy В результате будет создано большое количество дескрипторов, потребляющих значительные ресурсы. Кроме того, хотя нативный код может использовать только последний дескриптор, все связанные с ними объекты также будут оставаться живыми, поскольку все они принадлежат одной области.
Для этого случая Node-API предоставляет возможность создавать новую «область», с которой будут связываться вновь созданные дескрипторы. Когда эти дескрипторы больше не нужны, область можно «закрыть», и все связанные с ней дескрипторы станут недействительными. Для открытия и закрытия областей доступны методы napi_open_handle_scope и napi_close_handle_scope.
Node-API поддерживает только одну вложенную иерархию областей. В любой момент времени активна только одна область, и все новые дескрипторы связываются с ней, пока она активна. Области необходимо закрывать в обратном порядке относительно порядка их открытия. Кроме того, все области, созданные в нативном методе, должны быть закрыты до его завершения.
В рассмотренном выше примере добавление вызовов napi_open_handle_scope и napi_close_handle_scope гарантирует, что на протяжении выполнения цикла будет действителен не более чем один дескриптор:
for (int i = 0; i < 1000000; i++) {
napi_handle_scope scope;
napi_status status = napi_open_handle_scope(env, &scope);
if (status != napi_ok) {
break;
}
napi_value result;
status = napi_get_element(env, object, i, &result);
if (status != napi_ok) {
break;
}
// do something with element
status = napi_close_handle_scope(env, scope);
if (status != napi_ok) {
break;
}
} copy При вложении областей бывают случаи, когда дескриптор из внутренней области должен оставаться действительным дольше времени жизни этой области. Для этого случая Node-API поддерживает «область с возможностью выхода». Такая область позволяет «повысить» один дескриптор, чтобы он «вышел» за пределы текущей области и его время жизни изменилось с времени жизни текущей области на время жизни внешней области.
Для открытия и закрытия областей с возможностью выхода доступны методы napi_open_escapable_handle_scope и napi_close_escapable_handle_scope.
Запрос на повышение дескриптора выполняется с помощью napi_escape_handle, который можно вызвать только один раз.
napi_open_handle_scope
NAPI_EXTERN napi_status napi_open_handle_scope(napi_env env,
napi_handle_scope* result); copy -
[in] env: среда, в которой вызывается API. -
[out] result:napi_value, представляющий новую область.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API открывает новую область.
napi_close_handle_scope
NAPI_EXTERN napi_status napi_close_handle_scope(napi_env env,
napi_handle_scope scope); copy -
[in] env: среда, в которой вызывается API. -
[in] scope:napi_value, представляющий закрываемую область.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API закрывает переданную область. Области необходимо закрывать в обратном порядке относительно порядка их создания.
Этот API можно вызвать, даже если имеется необработанное исключение JavaScript.
napi_open_escapable_handle_scope
NAPI_EXTERN napi_status
napi_open_escapable_handle_scope(napi_env env,
napi_handle_scope* result); copy -
[in] env: среда, в которой вызывается API. -
[out] result:napi_value, представляющий новую область.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API открывает новую область, из которой один объект можно перенести во внешнюю область.
napi_close_escapable_handle_scope
NAPI_EXTERN napi_status
napi_close_escapable_handle_scope(napi_env env,
napi_handle_scope scope); copy -
[in] env: среда, в которой вызывается API. -
[in] scope:napi_value, представляющий закрываемую область.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API закрывает переданную область. Области необходимо закрывать в обратном порядке относительно порядка их создания.
Этот API можно вызвать, даже если имеется необработанное исключение JavaScript.
napi_escape_handle
napi_status napi_escape_handle(napi_env env,
napi_escapable_handle_scope scope,
napi_value escapee,
napi_value* result); copy -
[in] env: среда, в которой вызывается API. -
[in] scope:napi_value, представляющий текущую область. -
[in] escapee:napi_value, представляющий JavaScript-объектObject, который нужно вывести из области. -
[out] result:napi_value, представляющий дескриптор выведенногоObjectво внешней области.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API повышает дескриптор JavaScript-объекта, чтобы он оставался действительным в течение времени жизни внешней области. Его можно вызвать только один раз для каждой области. При повторном вызове будет возвращена ошибка.
Этот API можно вызвать, даже если имеется необработанное исключение JavaScript.
Ссылки на значения, время жизни которых превышает время жизни нативного метода
В некоторых случаях дополнению необходимо создавать значения со временем жизни, превышающим время выполнения одного вызова нативного метода, и ссылаться на них. Например, чтобы создать конструктор и позднее использовать его для создания экземпляров, необходимо иметь возможность обращаться к объекту конструктора в нескольких запросах на создание экземпляров. Это было бы невозможно с обычным дескриптором, возвращаемым как napi_value, как описано в предыдущем разделе. Время жизни обычного дескриптора управляется областями, и все области должны быть закрыты до завершения нативного метода.
Node-API предоставляет методы для создания постоянных ссылок на значения. В настоящее время Node-API позволяет создавать ссылки только на ограниченный набор типов значений, включая объекты, внешние объекты, функции и символы.
С каждой ссылкой связан счетчик со значением 0 или выше, который определяет, будет ли ссылка удерживать соответствующее значение живым. Ссылки со счетчиком 0 не препятствуют сборке значений. Значения типов object (объект, функция, внешний объект) и symbol становятся «слабыми» ссылками и остаются доступными, пока не будут собраны. Любое значение счетчика больше 0 предотвращает сборку значений.
У значений типа symbol есть разновидности. Настоящее поведение слабой ссылки поддерживается только для локальных символов, созданных функцией napi_create_symbol или вызовами конструктора JavaScript Symbol(). Зарегистрированные глобально символы, созданные функцией node_api_symbol_for или вызовами функции JavaScript Symbol.for(), всегда остаются сильными ссылками, поскольку сборщик мусора их не собирает. То же относится к известным символам, например Symbol.iterator. Сборщик мусора также никогда их не собирает.
Ссылки можно создавать с начальным значением счетчика ссылок. Затем счетчик можно изменить с помощью napi_reference_ref и napi_reference_unref. Если объект собран при нулевом значении счетчика ссылки, все последующие вызовы для получения объекта, связанного со ссылкой, napi_get_reference_value вернут NULL для возвращаемого значения napi_value. Попытка вызвать napi_reference_ref для ссылки, объект которой уже собран, приводит к ошибке.
Ссылки необходимо удалять, когда они больше не нужны дополнению. После удаления ссылка больше не будет препятствовать сборке соответствующего объекта. Если не удалить постоянную ссылку, возникнет «утечка памяти»: нативная память, выделенная под постоянную ссылку, и соответствующий объект в куче будут удерживаться бесконечно.
Можно создать несколько постоянных ссылок на один и тот же объект. Каждая из них будет удерживать объект живым или нет в зависимости от собственного счетчика. Несколько постоянных ссылок на один объект могут привести к неожиданному удержанию нативной памяти. Нативные структуры постоянной ссылки должны оставаться доступными до вызова финализаторов для объекта, на который она указывает. Если для того же объекта создана новая постоянная ссылка, финализаторы этого объекта не будут вызваны, а нативная память, на которую указывала предыдущая постоянная ссылка, не будет освобождена. Этого можно избежать, по возможности вызывая napi_delete_reference вместе с napi_reference_unref.
История изменений:
-
Версия 10 (
NAPI_VERSIONопределен как10или выше):Ссылки можно создавать для всех типов значений. Новые поддерживаемые типы значений не поддерживают семантику слабых ссылок; значения этих типов освобождаются, когда счетчик ссылок становится равен 0, и после этого их уже нельзя получить по ссылке.
napi_create_reference
NAPI_EXTERN napi_status napi_create_reference(napi_env env,
napi_value value,
uint32_t initial_refcount,
napi_ref* result); copy -
[in] env: среда, в которой вызывается API. -
[in] value:napi_value, для которого создается ссылка. -
[in] initial_refcount: начальное значение счетчика ссылок для новой ссылки. -
[out] result:napi_ref, указывающий на новую ссылку.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API создает новую ссылку на переданное значение с указанным счетчиком ссылок.
napi_delete_reference
NAPI_EXTERN napi_status napi_delete_reference(napi_env env, napi_ref ref); copy
-
[in] env: среда, в которой вызывается API. -
[in] ref:napi_ref, которую необходимо удалить.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API удаляет переданную ссылку.
Этот API можно вызвать, даже если имеется необработанное исключение JavaScript.
napi_reference_ref
NAPI_EXTERN napi_status napi_reference_ref(napi_env env,
napi_ref ref,
uint32_t* result); copy -
[in] env: среда, в которой вызывается API. -
[in] ref:napi_ref, счетчик ссылок которой будет увеличен. -
[out] result: новое значение счетчика ссылок.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API увеличивает счетчик ссылок для переданной ссылки и возвращает полученное значение счетчика.
napi_reference_unref
NAPI_EXTERN napi_status napi_reference_unref(napi_env env,
napi_ref ref,
uint32_t* result); copy -
[in] env: среда, в которой вызывается API. -
[in] ref:napi_ref, счетчик ссылок которой будет уменьшен. -
[out] result: новое значение счетчика ссылок.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API уменьшает счетчик ссылок для переданной ссылки и возвращает полученное значение счетчика.
napi_get_reference_value
NAPI_EXTERN napi_status napi_get_reference_value(napi_env env,
napi_ref ref,
napi_value* result); copy -
[in] env: среда, в которой вызывается API. -
[in] ref:napi_ref, для которой запрашивается соответствующее значение. -
[out] result:napi_value, на которую указываетnapi_ref.
Возвращает napi_ok, если вызов API выполнен успешно.
Если ссылка еще действительна, этот API возвращает napi_value, представляющий значение JavaScript, связанное с napi_ref. В противном случае результатом будет NULL.
Очистка при завершении текущей среды Node.js
Обычно процесс Node.js освобождает все свои ресурсы при завершении. Однако встраиваемые версии Node.js или будущая поддержка Worker могут требовать, чтобы дополнения регистрировали обработчики очистки, вызываемые при завершении текущей среды Node.js.
Node-API предоставляет функции для регистрации и отмены регистрации таких обратных вызовов. При вызове этих обратных вызовов должны освобождаться все ресурсы, удерживаемые дополнением.
napi_add_env_cleanup_hook
NODE_EXTERN napi_status napi_add_env_cleanup_hook(node_api_basic_env env,
napi_cleanup_hook fun,
void* arg); copy Регистрирует fun как функцию, которая будет вызвана с параметром arg при завершении текущей среды Node.js.
Одну и ту же функцию можно безопасно указать несколько раз с разными значениями arg. В этом случае она также будет вызвана несколько раз. Повторно передавать одинаковые значения fun и arg нельзя; это приведет к аварийному завершению процесса.
Обработчики вызываются в обратном порядке: первым будет вызван последний добавленный обработчик.
Удалить этот обработчик можно с помощью napi_remove_env_cleanup_hook. Обычно это делают при освобождении ресурса, для которого был добавлен обработчик.
Для асинхронной очистки доступен napi_add_async_cleanup_hook.
napi_remove_env_cleanup_hook
NAPI_EXTERN napi_status napi_remove_env_cleanup_hook(node_api_basic_env env,
void (*fun)(void* arg),
void* arg); copy Отменяет регистрацию fun как функции, которая должна быть вызвана с параметром arg при завершении текущей среды Node.js. Аргумент и значение функции должны в точности совпадать с исходными.
Функция должна быть предварительно зарегистрирована с помощью napi_add_env_cleanup_hook, иначе процесс завершится аварийно.
napi_add_async_cleanup_hook
NAPI_EXTERN napi_status napi_add_async_cleanup_hook(
node_api_basic_env env,
napi_async_cleanup_hook hook,
void* arg,
napi_async_cleanup_hook_handle* remove_handle); copy -
[in] env: среда, в которой вызывается API. -
[in] hook: указатель на функцию, вызываемую при завершении работы среды. -
[in] arg: указатель, передаваемый вhookпри вызове. -
[out] remove_handle: необязательный дескриптор асинхронного обработчика очистки.
Регистрирует hook — функцию типа napi_async_cleanup_hook, которая будет вызвана с параметрами remove_handle и arg при завершении текущей среды Node.js.
В отличие от napi_add_env_cleanup_hook, этот обработчик может быть асинхронным.
В остальном поведение в целом соответствует поведению napi_add_env_cleanup_hook.
Если remove_handle не равен NULL, в него будет записано непрозрачное значение, которое впоследствии необходимо передать в napi_remove_async_cleanup_hook, независимо от того, был ли обработчик уже вызван. Обычно это делают при освобождении ресурса, для которого был добавлен обработчик.
napi_remove_async_cleanup_hook
NAPI_EXTERN napi_status napi_remove_async_cleanup_hook(
napi_async_cleanup_hook_handle remove_handle); copy -
[in] remove_handle: дескриптор асинхронного обработчика очистки, созданного с помощьюnapi_add_async_cleanup_hook.
Отменяет регистрацию обработчика очистки, соответствующего remove_handle. Это предотвратит выполнение обработчика, если его выполнение еще не началось. Этот вызов необходимо выполнить для каждого значения napi_async_cleanup_hook_handle, полученного с помощью napi_add_async_cleanup_hook.
Финализация при завершении среды Node.js
Среда Node.js может быть завершена в произвольный момент, как только это станет возможным, с запретом выполнения JavaScript, например по запросу worker.terminate(). При завершении среды зарегистрированные обратные вызовы napi_finalize объектов JavaScript, потокобезопасных функций и данных экземпляра среды вызываются немедленно и независимо друг от друга.
Вызовы обратных вызовов napi_finalize планируются после вручную зарегистрированных обработчиков очистки. Чтобы обеспечить правильный порядок финализации дополнений при завершении среды и избежать обращения к освобожденной памяти в обратном вызове napi_finalize, дополнениям следует регистрировать обработчик очистки с помощью napi_add_env_cleanup_hook и napi_add_async_cleanup_hook для ручного освобождения выделенного ресурса в надлежащем порядке.
Регистрация модулей
Модули Node-API регистрируются так же, как и другие модули, за исключением того, что вместо макроса NODE_MODULE используется следующий код:
NAPI_MODULE(NODE_GYP_MODULE_NAME, Init) copy
Следующее отличие касается сигнатуры метода Init. Для модуля Node-API она выглядит следующим образом:
napi_value Init(napi_env env, napi_value exports); copy
Возвращаемое значение Init используется как объект exports модуля. Для удобства методу Init передается пустой объект через параметр exports. Если Init возвращает NULL, модуль экспортирует параметр, переданный как exports. Модули Node-API не могут изменять объект module, но могут указать любое значение в качестве свойства exports модуля.
Чтобы добавить метод hello в качестве функции, доступной для вызова как метода, предоставляемого дополнением:
napi_value Init(napi_env env, napi_value exports) {
napi_status status;
napi_property_descriptor desc = {
"hello",
NULL,
Method,
NULL,
NULL,
NULL,
napi_writable | napi_enumerable | napi_configurable,
NULL
};
status = napi_define_properties(env, exports, 1, &desc);
if (status != napi_ok) return NULL;
return exports;
} copy Чтобы задать функцию, возвращаемую require() дополнения:
napi_value Init(napi_env env, napi_value exports) {
napi_value method;
napi_status status;
status = napi_create_function(env, "exports", NAPI_AUTO_LENGTH, Method, NULL, &method);
if (status != napi_ok) return NULL;
return method;
} copy Чтобы определить класс, экземпляры которого можно создавать (часто используется с оберткой объекта):
// NOTE: partial example, not all referenced code is included
napi_value Init(napi_env env, napi_value exports) {
napi_status status;
napi_property_descriptor properties[] = {
{ "value", NULL, NULL, GetValue, SetValue, NULL, napi_writable | napi_configurable, NULL },
DECLARE_NAPI_METHOD("plusOne", PlusOne),
DECLARE_NAPI_METHOD("multiply", Multiply),
};
napi_value cons;
status =
napi_define_class(env, "MyObject", New, NULL, 3, properties, &cons);
if (status != napi_ok) return NULL;
status = napi_create_reference(env, cons, 1, &constructor);
if (status != napi_ok) return NULL;
status = napi_set_named_property(env, exports, "MyObject", cons);
if (status != napi_ok) return NULL;
return exports;
} copy Можно также использовать макрос NAPI_MODULE_INIT, который является сокращенной записью для NAPI_MODULE и определения функции Init:
NAPI_MODULE_INIT(/* napi_env env, napi_value exports */) {
napi_value answer;
napi_status result;
status = napi_create_int64(env, 42, &answer);
if (status != napi_ok) return NULL;
status = napi_set_named_property(env, exports, "answer", answer);
if (status != napi_ok) return NULL;
return exports;
} copy Параметры env и exports доступны в теле макроса NAPI_MODULE_INIT.
Все дополнения Node-API учитывают контекст, то есть их можно загружать несколько раз. При объявлении такого модуля необходимо учитывать несколько особенностей проектирования. Дополнительные сведения приведены в документации о дополнениях с учетом контекста.
Переменные env и exports будут доступны в теле функции после вызова макроса.
Подробнее о задании свойств объектов см. в разделе Работа со свойствами JavaScript.
Общие сведения о создании модулей-дополнений см. в существующей документации API.
Работа со значениями JavaScript
Node-API предоставляет набор API для создания всех типов значений JavaScript. Некоторые из этих типов описаны в разделе «Типы языка» спецификации языка ECMAScript.
В основном эти API используются для выполнения одного из следующих действий:
- Создание нового объекта JavaScript
- Преобразование примитивного типа C в значение Node-API
- Преобразование значения Node-API в примитивный тип C
- Получение глобальных экземпляров, включая
undefinedиnull
Значения Node-API представлены типом napi_value. Любой вызов Node-API, которому требуется значение JavaScript, принимает napi_value. В некоторых случаях API заранее проверяет тип napi_value. Однако для повышения производительности вызывающему коду лучше убедиться, что нужный napi_value имеет ожидаемый API тип JavaScript.
Типы перечислений
napi_key_collection_mode
typedef enum {
napi_key_include_prototypes,
napi_key_own_only
} napi_key_collection_mode; copy Описывает перечисления фильтра Keys/Properties:
napi_key_collection_mode ограничивает диапазон собираемых свойств.
napi_key_own_only ограничивает собираемые свойства только заданным объектом. napi_key_include_prototypes также включает все ключи цепочки прототипов объекта.
napi_key_filter
typedef enum {
napi_key_all_properties = 0,
napi_key_writable = 1,
napi_key_enumerable = 1 << 1,
napi_key_configurable = 1 << 2,
napi_key_skip_strings = 1 << 3,
napi_key_skip_symbols = 1 << 4
} napi_key_filter; copy Битовый флаг фильтра свойств. Для построения составного фильтра используются побитовые операторы.
napi_key_conversion
typedef enum {
napi_key_keep_numbers,
napi_key_numbers_to_strings
} napi_key_conversion; copy napi_key_numbers_to_strings преобразует целочисленные индексы в строки. napi_key_keep_numbers возвращает числа для целочисленных индексов.
napi_valuetype
typedef enum {
// ES6 types (corresponds to typeof)
napi_undefined,
napi_null,
napi_boolean,
napi_number,
napi_string,
napi_symbol,
napi_object,
napi_function,
napi_external,
napi_bigint,
} napi_valuetype; copy Описывает тип napi_value. Обычно он соответствует типам, описанным в разделе «Типы языка» спецификации языка ECMAScript. Помимо типов из этого раздела, napi_valuetype может также представлять Function и Object с внешними данными.
Значение JavaScript типа napi_external представлено в JavaScript как обычный объект, которому нельзя присваивать свойства и у которого нет прототипа.
napi_typedarray_type
typedef enum {
napi_int8_array,
napi_uint8_array,
napi_uint8_clamped_array,
napi_int16_array,
napi_uint16_array,
napi_int32_array,
napi_uint32_array,
napi_float32_array,
napi_float64_array,
napi_bigint64_array,
napi_biguint64_array,
} napi_typedarray_type; copy Этот тип представляет базовый двоичный скалярный тип данных TypedArray. Элементы этого перечисления соответствуют разделу «Объекты TypedArray» спецификации языка ECMAScript.
Функции создания объектов
napi_create_array
napi_status napi_create_array(napi_env env, napi_value* result) copy
-
[in] env: среда, в которой вызывается функция Node-API. -
[out] result:napi_value, представляющий массив JavaScriptArray.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API возвращает значение Node-API, соответствующее типу JavaScript Array. Массивы JavaScript описаны в разделе «Объекты Array» спецификации языка ECMAScript.
napi_create_array_with_length
napi_status napi_create_array_with_length(napi_env env,
size_t length,
napi_value* result) copy -
[in] env: среда, в которой вызывается API. -
[in] length: начальная длинаArray. -
[out] result:napi_value, представляющий массив JavaScriptArray.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API возвращает значение Node-API, соответствующее типу JavaScript Array. Свойству length объекта Array присваивается переданный параметр длины. Однако виртуальная машина не гарантирует предварительное выделение базового буфера при создании массива. Такое поведение определяется реализацией базовой виртуальной машины. Если требуется, чтобы буфер представлял собой непрерывный блок памяти, который можно напрямую читать и/или записывать из C, рассмотрите возможность использования napi_create_external_arraybuffer.
Массивы JavaScript описаны в разделе «Объекты Array» спецификации языка ECMAScript.
napi_create_arraybuffer
napi_status napi_create_arraybuffer(napi_env env,
size_t byte_length,
void** data,
napi_value* result) copy -
[in] env: среда, в которой вызывается API. -
[in] length: длина создаваемого буфера массива в байтах. -
[out] data: указатель на базовый байтовый буферArrayBuffer. Параметрdataможно не использовать, передавNULL. -
[out] result:napi_value, представляющийArrayBufferJavaScript.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API возвращает значение Node-API, соответствующее ArrayBuffer JavaScript. ArrayBuffer используются для представления буферов двоичных данных фиксированной длины. Обычно они служат буфером-основой для объектов TypedArray. Для выделенного ArrayBuffer создается базовый байтовый буфер размером, определяемым переданным параметром length. Базовый буфер может быть возвращен вызывающему коду, если тот хочет напрямую работать с ним. Записывать данные в этот буфер напрямую может только нативный код. Для записи данных в него из JavaScript необходимо создать типизированный массив или объект DataView.
Объекты JavaScript ArrayBuffer описаны в разделе «Объекты ArrayBuffer» спецификации языка ECMAScript.
napi_create_buffer
napi_status napi_create_buffer(napi_env env,
size_t size,
void** data,
napi_value* result) copy -
[in] env: среда, в которой вызывается API. -
[in] size: размер базового буфера в байтах. -
[out] data: указатель на базовый буфер. Параметрdataможно не использовать, передавNULL. -
[out] result:napi_value, представляющийnode::Buffer.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API выделяет объект node::Buffer. Хотя эта структура данных по-прежнему полностью поддерживается, в большинстве случаев достаточно использовать TypedArray.
napi_create_buffer_copy
napi_status napi_create_buffer_copy(napi_env env,
size_t length,
const void* data,
void** result_data,
napi_value* result) copy -
[in] env: среда, в которой вызывается API. -
[in] size: размер входного буфера в байтах (должен совпадать с размером нового буфера). -
[in] data: указатель на исходный базовый буфер, из которого выполняется копирование. -
[out] result_data: указатель на базовый буфер данных новогоBuffer. Параметрresult_dataможно не использовать, передавNULL. -
[out] result:napi_value, представляющийnode::Buffer.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API выделяет объект node::Buffer и инициализирует его данными, скопированными из переданного буфера. Хотя эта структура данных по-прежнему полностью поддерживается, в большинстве случаев достаточно использовать TypedArray.
napi_create_date
napi_status napi_create_date(napi_env env,
double time,
napi_value* result); copy -
[in] env: среда, в которой вызывается API. -
[in] time: значение времени ECMAScript в миллисекундах с 1 января 1970 года по UTC. -
[out] result:napi_value, представляющийDateJavaScript.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API не учитывает високосные секунды: они игнорируются, поскольку ECMAScript соответствует спецификации времени POSIX.
Этот API выделяет объект JavaScript Date.
Объекты JavaScript Date описаны в разделе «Объекты Date» спецификации языка ECMAScript.
napi_create_external
napi_status napi_create_external(napi_env env,
void* data,
napi_finalize finalize_cb,
void* finalize_hint,
napi_value* result) copy -
[in] env: среда, в которой вызывается API. -
[in] data: указатель на внешние данные. -
[in] finalize_cb: необязательный обратный вызов, вызываемый при сборке внешнего значения. Дополнительные сведения см. в разделеnapi_finalize. -
[in] finalize_hint: необязательная подсказка, передаваемая обратному вызову финализации во время сборки. -
[out] result:napi_value, представляющий внешнее значение.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API создает значение JavaScript, связанное с внешними данными. Оно используется для передачи внешних данных через код JavaScript, чтобы позднее их можно было получить из нативного кода с помощью napi_get_value_external.
API добавляет обратный вызов napi_finalize, который будет вызван после сборки мусора для только что созданного объекта JavaScript.
Созданное значение не является объектом и поэтому не поддерживает дополнительные свойства. Оно считается отдельным типом значения: вызов napi_typeof() для внешнего значения возвращает napi_external.
napi_create_external_arraybuffer
napi_status
napi_create_external_arraybuffer(napi_env env,
void* external_data,
size_t byte_length,
napi_finalize finalize_cb,
void* finalize_hint,
napi_value* result) copy -
[in] env: среда, в которой вызывается API. -
[in] external_data: указатель на базовый байтовый буферArrayBuffer. -
[in] byte_length: длина базового буфера в байтах. -
[in] finalize_cb: необязательный обратный вызов, вызываемый при сборкеArrayBuffer. Дополнительные сведения см. в разделеnapi_finalize. -
[in] finalize_hint: необязательная подсказка, передаваемая обратному вызову финализации во время сборки. -
[out] result:napi_value, представляющийArrayBufferJavaScript.
Возвращает napi_ok, если вызов API выполнен успешно.
В некоторых средах выполнения, отличных от Node.js, поддержка внешних буферов была прекращена. В таких средах этот метод может возвращать napi_no_external_buffers_allowed, указывая на отсутствие поддержки внешних буферов. Одним из таких примеров является Electron, о чем говорится в этой задаче: electron/issues/35801.
Чтобы обеспечить максимальную совместимость со всеми средами выполнения, можно определить NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED в своем дополнении до подключения заголовочных файлов node-api. Это скроет две функции для создания внешних буферов и гарантирует возникновение ошибки компиляции, если вы случайно воспользуетесь одним из этих методов.
Этот API возвращает значение Node-API, соответствующее ArrayBuffer JavaScript. Базовый байтовый буфер ArrayBuffer выделяется и управляется извне. Вызывающий код должен обеспечить действительность байтового буфера до вызова обратного вызова финализации.
API добавляет обратный вызов napi_finalize, который будет вызван после сборки мусора для только что созданного объекта JavaScript.
Объекты JavaScript ArrayBuffer описаны в разделе «Объекты ArrayBuffer» спецификации языка ECMAScript.
napi_create_external_buffer
napi_status napi_create_external_buffer(napi_env env,
size_t length,
void* data,
napi_finalize finalize_cb,
void* finalize_hint,
napi_value* result) copy -
[in] env: среда, в которой вызывается API. -
[in] length: размер входного буфера в байтах (должен совпадать с размером нового буфера). -
[in] data: указатель на базовый буфер, который будет доступен JavaScript. -
[in] finalize_cb: необязательный обратный вызов, вызываемый при сборкеArrayBuffer. Дополнительные сведения см. в разделеnapi_finalize. -
[in] finalize_hint: необязательная подсказка, передаваемая обратному вызову финализации во время сборки. -
[out] result:napi_value, представляющийnode::Buffer.
Возвращает napi_ok, если вызов API выполнен успешно.
В некоторых средах выполнения, отличных от Node.js, поддержка внешних буферов была прекращена. В таких средах этот метод может возвращать napi_no_external_buffers_allowed, указывая на отсутствие поддержки внешних буферов. Одним из таких примеров является Electron, о чем говорится в этой задаче: electron/issues/35801.
Чтобы обеспечить максимальную совместимость со всеми средами выполнения, можно определить NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED в своем дополнении до подключения заголовочных файлов node-api. Это скроет две функции для создания внешних буферов и гарантирует возникновение ошибки компиляции, если вы случайно воспользуетесь одним из этих методов.
Этот API выделяет объект node::Buffer и инициализирует его данными, хранящимися в переданном буфере. Хотя эта структура данных по-прежнему полностью поддерживается, в большинстве случаев достаточно использовать TypedArray.
API добавляет обратный вызов napi_finalize, который будет вызван после сборки мусора для только что созданного объекта JavaScript.
В Node.js >=4 объекты Buffers являются Uint8Array.
napi_create_object
napi_status napi_create_object(napi_env env, napi_value* result) copy
-
[in] env: среда, в которой вызывается API. -
[out] result:napi_value, представляющий объект JavaScriptObject.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API выделяет объект JavaScript Object по умолчанию. Это эквивалентно выполнению new Object() в JavaScript.
Тип JavaScript Object описан в разделе «Тип object» спецификации языка ECMAScript.
napi_create_symbol
napi_status napi_create_symbol(napi_env env,
napi_value description,
napi_value* result) copy -
[in] env: среда, в которой вызывается API. -
[in] description: необязательныйnapi_value, указывающий наstringJavaScript, который будет задан в качестве описания символа. -
[out] result:napi_value, представляющийsymbolJavaScript.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API создает значение symbol JavaScript из строки C в кодировке UTF-8.
Тип JavaScript symbol описан в разделе «Тип symbol» спецификации языка ECMAScript.
node_api_symbol_for
napi_status node_api_symbol_for(napi_env env,
const char* utf8description,
size_t length,
napi_value* result) copy -
[in] env: среда, в которой вызывается API. -
[in] utf8description: строка C в кодировке UTF-8, содержащая текст, который будет использоваться в качестве описания символа. -
[in] length: длина строки описания в байтах илиNAPI_AUTO_LENGTH, если строка завершается нулевым символом. -
[out] result:napi_value, представляющийsymbolJavaScript.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API ищет в глобальном реестре символ с заданным описанием. Если символ уже существует, он будет возвращен; в противном случае в реестре будет создан новый символ.
Тип JavaScript symbol описан в разделе «Тип symbol» спецификации языка ECMAScript.
napi_create_typedarray
napi_status napi_create_typedarray(napi_env env,
napi_typedarray_type type,
size_t length,
napi_value arraybuffer,
size_t byte_offset,
napi_value* result) copy -
[in] env: среда, в которой вызывается API. -
[in] type: скалярный тип данных элементовTypedArray. -
[in] length: количество элементов вTypedArray. -
[in] arraybuffer:ArrayBuffer, лежащий в основе типизированного массива. -
[in] byte_offset: смещение в байтах внутриArrayBuffer, с которого начинается представлениеTypedArray. -
[out] result:napi_value, представляющийTypedArrayJavaScript.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API создает объект JavaScript TypedArray на основе существующего ArrayBuffer. Объекты TypedArray предоставляют подобное массиву представление базового буфера данных, в котором каждый элемент имеет один и тот же базовый двоичный скалярный тип данных.
Необходимо, чтобы (length * size_of_element) + byte_offset было меньше или равно размеру переданного массива в байтах. В противном случае возникает исключение RangeError.
Объекты JavaScript TypedArray описаны в разделе «Объекты TypedArray» спецификации языка ECMAScript.
node_api_create_buffer_from_arraybuffer
napi_status NAPI_CDECL node_api_create_buffer_from_arraybuffer(napi_env env,
napi_value arraybuffer,
size_t byte_offset,
size_t byte_length,
napi_value* result) copy -
[in] env: среда, в которой вызывается API. -
[in] arraybuffer:ArrayBuffer, из которого будет создан буфер. -
[in] byte_offset: смещение в байтах внутриArrayBuffer, с которого начинается создание буфера. -
[in] byte_length: длина создаваемого изArrayBufferбуфера в байтах. -
[out] result:napi_value, представляющий созданный объект JavaScriptBuffer.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API создает объект JavaScript Buffer на основе существующего ArrayBuffer. Объект Buffer — это специфичный для Node.js класс, предоставляющий возможность напрямую работать с двоичными данными в JavaScript.
Диапазон байтов [byte_offset, byte_offset + byte_length) должен находиться в пределах ArrayBuffer. Если byte_offset + byte_length превышает размер ArrayBuffer, возникает исключение RangeError.
napi_create_dataview
napi_status napi_create_dataview(napi_env env,
size_t byte_length,
napi_value arraybuffer,
size_t byte_offset,
napi_value* result) copy -
[in] env: среда, в которой вызывается API. -
[in] length: количество элементов вDataView. -
[in] arraybuffer:ArrayBuffer, лежащий в основеDataView. -
[in] byte_offset: смещение в байтах внутриArrayBuffer, с которого начинается представлениеDataView. -
[out] result:napi_value, представляющийDataViewJavaScript.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API создает объект JavaScript DataView на основе существующего ArrayBuffer. Объекты DataView предоставляют подобное массиву представление базового буфера данных, но позволяют хранить в ArrayBuffer элементы разных размеров и типов.
Необходимо, чтобы byte_length + byte_offset было меньше или равно размеру переданного массива в байтах. В противном случае возникает исключение RangeError.
Объекты JavaScript DataView описаны в разделе «Объекты DataView» спецификации языка ECMAScript.
Функции для преобразования типов C в Node-API
napi_create_int32
napi_status napi_create_int32(napi_env env, int32_t value, napi_value* result) copy
-
[in] env: Среда, в которой вызывается API. -
[in] value: Целочисленное значение, которое должно быть представлено в JavaScript. -
[out] result:napi_value, представляющий JavaScriptnumber.
Возвращает napi_ok, если API выполнен успешно.
Этот API используется для преобразования типа C int32_t в тип JavaScript number.
Тип JavaScript number описан в разделе «Тип Number» спецификации языка ECMAScript.
napi_create_uint32
napi_status napi_create_uint32(napi_env env, uint32_t value, napi_value* result) copy
-
[in] env: Среда, в которой вызывается API. -
[in] value: Беззнаковое целочисленное значение, которое должно быть представлено в JavaScript. -
[out] result:napi_value, представляющий JavaScriptnumber.
Возвращает napi_ok, если API выполнен успешно.
Этот API используется для преобразования типа C uint32_t в тип JavaScript number.
Тип JavaScript number описан в разделе «Тип Number» спецификации языка ECMAScript.
napi_create_int64
napi_status napi_create_int64(napi_env env, int64_t value, napi_value* result) copy
-
[in] env: Среда, в которой вызывается API. -
[in] value: Целочисленное значение, которое должно быть представлено в JavaScript. -
[out] result:napi_value, представляющий JavaScriptnumber.
Возвращает napi_ok, если API выполнен успешно.
Этот API используется для преобразования типа C int64_t в тип JavaScript number.
Тип JavaScript number описан в разделе «Тип Number» спецификации языка ECMAScript. Учтите, что весь диапазон int64_t невозможно представить в JavaScript с полной точностью. Целочисленные значения вне диапазона от Number.MIN_SAFE_INTEGER -(2**53 - 1) до Number.MAX_SAFE_INTEGER (2**53 - 1) будут терять точность.
napi_create_double
napi_status napi_create_double(napi_env env, double value, napi_value* result) copy
-
[in] env: Среда, в которой вызывается API. -
[in] value: Значение двойной точности, которое должно быть представлено в JavaScript. -
[out] result:napi_value, представляющий JavaScriptnumber.
Возвращает napi_ok, если API выполнен успешно.
Этот API используется для преобразования типа C double в тип JavaScript number.
Тип JavaScript number описан в разделе «Тип Number» спецификации языка ECMAScript.
napi_create_bigint_int64
napi_status napi_create_bigint_int64(napi_env env,
int64_t value,
napi_value* result); copy -
[in] env: Среда, в которой вызывается API. -
[in] value: Целочисленное значение, которое должно быть представлено в JavaScript. -
[out] result:napi_value, представляющий JavaScriptBigInt.
Возвращает napi_ok, если API выполнен успешно.
Этот API преобразует тип C int64_t в тип JavaScript BigInt.
napi_create_bigint_uint64
napi_status napi_create_bigint_uint64(napi_env env,
uint64_t value,
napi_value* result); copy -
[in] env: Среда, в которой вызывается API. -
[in] value: Беззнаковое целочисленное значение, которое должно быть представлено в JavaScript. -
[out] result:napi_value, представляющий JavaScriptBigInt.
Возвращает napi_ok, если API выполнен успешно.
Этот API преобразует тип C uint64_t в тип JavaScript BigInt.
napi_create_bigint_words
napi_status napi_create_bigint_words(napi_env env,
int sign_bit,
size_t word_count,
const uint64_t* words,
napi_value* result); copy -
[in] env: Среда, в которой вызывается API. -
[in] sign_bit: Определяет, будет ли результирующийBigIntположительным или отрицательным. -
[in] word_count: Длина массиваwords. -
[in] words: Массив 64-битных словuint64_tв порядке от младшего байта к старшему. -
[out] result:napi_value, представляющий JavaScriptBigInt.
Возвращает napi_ok, если API выполнен успешно.
Этот API преобразует массив беззнаковых 64-битных слов в одно значение BigInt.
Результирующее значение BigInt вычисляется по формуле: (–1)sign_bit (words[0] × (264)0 + words[1] × (264)1 + …)
napi_create_string_latin1
napi_status napi_create_string_latin1(napi_env env,
const char* str,
size_t length,
napi_value* result); copy -
[in] env: Среда, в которой вызывается API. -
[in] str: Буфер символов, представляющий строку в кодировке ISO-8859-1. -
[in] length: Длина строки в байтах илиNAPI_AUTO_LENGTH, если строка завершается нулевым символом. -
[out] result:napi_value, представляющий JavaScriptstring.
Возвращает napi_ok, если API выполнен успешно.
Этот API создает значение JavaScript string из строки C в кодировке ISO-8859-1. Нативная строка копируется.
Тип JavaScript string описан в разделе «Тип String» спецификации языка ECMAScript.
node_api_create_external_string_latin1
napi_status
node_api_create_external_string_latin1(napi_env env,
char* str,
size_t length,
napi_finalize finalize_callback,
void* finalize_hint,
napi_value* result,
bool* copied); copy -
[in] env: Среда, в которой вызывается API. -
[in] str: Буфер символов, представляющий строку в кодировке ISO-8859-1. -
[in] length: Длина строки в байтах илиNAPI_AUTO_LENGTH, если строка завершается нулевым символом. -
[in] finalize_callback: Функция, вызываемая при сборке строки. Функция будет вызвана со следующими параметрами:-
[in] env: Среда, в которой выполняется дополнение. Это значение может быть null, если строка собирается в рамках завершения работы рабочего потока или основного экземпляра Node.js. -
[in] data: Это значениеstrв виде указателяvoid*. -
[in] finalize_hint: Это значениеfinalize_hint, переданное API. Дополнительные сведения см. в разделеnapi_finalize. Этот параметр необязателен. Передача значения null означает, что дополнению не нужно сообщать о сборке соответствующей строки JavaScript.
-
-
[in] finalize_hint: Необязательная подсказка, передаваемая функции обратного вызова финализации при сборке. -
[out] result:napi_value, представляющий JavaScriptstring. -
[out] copied: Было ли скопировано строковое значение. Если да, финализатор уже был вызван для освобожденияstr.
Возвращает napi_ok, если API выполнен успешно.
Этот API создает значение JavaScript string из строки C в кодировке ISO-8859-1. Нативная строка может не копироваться и поэтому должна существовать на протяжении всего жизненного цикла значения JavaScript.
Тип JavaScript string описан в разделе «Тип String» спецификации языка ECMAScript.
napi_create_string_utf16
napi_status napi_create_string_utf16(napi_env env,
const char16_t* str,
size_t length,
napi_value* result) copy -
[in] env: Среда, в которой вызывается API. -
[in] str: Буфер символов, представляющий строку в кодировке UTF16-LE. -
[in] length: Длина строки в двухбайтовых кодовых единицах илиNAPI_AUTO_LENGTH, если строка завершается нулевым символом. -
[out] result:napi_value, представляющий JavaScriptstring.
Возвращает napi_ok, если API выполнен успешно.
Этот API создает значение JavaScript string из строки C в кодировке UTF16-LE. Нативная строка копируется.
Тип JavaScript string описан в разделе «Тип String» спецификации языка ECMAScript.
node_api_create_external_string_utf16
napi_status
node_api_create_external_string_utf16(napi_env env,
char16_t* str,
size_t length,
napi_finalize finalize_callback,
void* finalize_hint,
napi_value* result,
bool* copied); copy -
[in] env: Среда, в которой вызывается API. -
[in] str: Буфер символов, представляющий строку в кодировке UTF16-LE. -
[in] length: Длина строки в двухбайтовых кодовых единицах илиNAPI_AUTO_LENGTH, если строка завершается нулевым символом. -
[in] finalize_callback: Функция, вызываемая при сборке строки. Функция будет вызвана со следующими параметрами:-
[in] env: Среда, в которой выполняется дополнение. Это значение может быть null, если строка собирается в рамках завершения работы рабочего потока или основного экземпляра Node.js. -
[in] data: Это значениеstrв виде указателяvoid*. -
[in] finalize_hint: Это значениеfinalize_hint, переданное API. Дополнительные сведения см. в разделеnapi_finalize. Этот параметр необязателен. Передача значения null означает, что дополнению не нужно сообщать о сборке соответствующей строки JavaScript.
-
-
[in] finalize_hint: Необязательная подсказка, передаваемая функции обратного вызова финализации при сборке. -
[out] result:napi_value, представляющий JavaScriptstring. -
[out] copied: Было ли скопировано строковое значение. Если да, финализатор уже был вызван для освобожденияstr.
Возвращает napi_ok, если API выполнен успешно.
Этот API создает значение JavaScript string из строки C в кодировке UTF16-LE. Нативная строка может не копироваться и поэтому должна существовать на протяжении всего жизненного цикла значения JavaScript.
Тип JavaScript string описан в разделе «Тип String» спецификации языка ECMAScript.
napi_create_string_utf8
napi_status napi_create_string_utf8(napi_env env,
const char* str,
size_t length,
napi_value* result) copy -
[in] env: Среда, в которой вызывается API. -
[in] str: Буфер символов, представляющий строку в кодировке UTF8. -
[in] length: Длина строки в байтах илиNAPI_AUTO_LENGTH, если строка завершается нулевым символом. -
[out] result:napi_value, представляющий JavaScriptstring.
Возвращает napi_ok, если API выполнен успешно.
Этот API создает значение JavaScript string из строки C в кодировке UTF8. Нативная строка копируется.
Тип JavaScript string описан в разделе «Тип String» спецификации языка ECMAScript.
Функции для создания оптимизированных ключей свойств
Многие движки JavaScript, включая V8, используют интернированные строки в качестве ключей для установки и получения значений свойств. Обычно для создания и поиска таких строк используется хеш-таблица. Создание каждого ключа требует дополнительных затрат, но впоследствии производительность повышается, поскольку вместо целых строк можно сравнивать указатели на строки.
Если новую строку JavaScript планируется использовать в качестве ключа свойства, то в некоторых движках JavaScript эффективнее использовать функции из этого раздела. В противном случае используйте функции серии napi_create_string_utf8 или node_api_create_external_string_utf8, так как методы создания ключей свойств могут создавать дополнительные накладные расходы при создании и хранении строк.
node_api_create_property_key_latin1
napi_status NAPI_CDECL node_api_create_property_key_latin1(napi_env env,
const char* str,
size_t length,
napi_value* result); copy -
[in] env: Среда, в которой вызывается API. -
[in] str: Буфер символов, представляющий строку в кодировке ISO-8859-1. -
[in] length: Длина строки в байтах илиNAPI_AUTO_LENGTH, если строка завершается нулевым символом. -
[out] result:napi_value, представляющий оптимизированную строку JavaScriptstringдля использования в качестве ключа свойства объекта.
Возвращает napi_ok, если API выполнен успешно.
Этот API создает оптимизированное значение JavaScript string из строки C в кодировке ISO-8859-1 для использования в качестве ключа свойства объекта. Нативная строка копируется. В отличие от napi_create_string_latin1, повторные вызовы этой функции с тем же указателем str могут ускорить создание запрошенного napi_value — в зависимости от движка.
Тип JavaScript string описан в разделе «Тип String» спецификации языка ECMAScript.
node_api_create_property_key_utf16
napi_status NAPI_CDECL node_api_create_property_key_utf16(napi_env env,
const char16_t* str,
size_t length,
napi_value* result); copy -
[in] env: Среда, в которой вызывается API. -
[in] str: Буфер символов, представляющий строку в кодировке UTF16-LE. -
[in] length: Длина строки в двухбайтовых кодовых единицах илиNAPI_AUTO_LENGTH, если строка завершается нулевым символом. -
[out] result:napi_value, представляющий оптимизированную строку JavaScriptstringдля использования в качестве ключа свойства объекта.
Возвращает napi_ok, если API выполнен успешно.
Этот API создает оптимизированное значение JavaScript string из строки C в кодировке UTF16-LE для использования в качестве ключа свойства объекта. Нативная строка копируется.
Тип JavaScript string описан в разделе «Тип String» спецификации языка ECMAScript.
node_api_create_property_key_utf8
napi_status NAPI_CDECL node_api_create_property_key_utf8(napi_env env,
const char* str,
size_t length,
napi_value* result); copy -
[in] env: Среда, в которой вызывается API. -
[in] str: Буфер символов, представляющий строку в кодировке UTF8. -
[in] length: Длина строки в двухбайтовых кодовых единицах илиNAPI_AUTO_LENGTH, если строка завершается нулевым символом. -
[out] result:napi_value, представляющий оптимизированную строку JavaScriptstringдля использования в качестве ключа свойства объекта.
Возвращает napi_ok, если API выполнен успешно.
Этот API создает оптимизированное значение JavaScript string из строки C в кодировке UTF8 для использования в качестве ключа свойства объекта. Нативная строка копируется.
Тип JavaScript string описан в разделе «Тип String» спецификации языка ECMAScript.
Функции для преобразования типов Node-API в типы C
napi_get_array_length
napi_status napi_get_array_length(napi_env env,
napi_value value,
uint32_t* result) copy -
[in] env: Среда, в которой вызывается API. -
[in] value:napi_value, представляющий массив JavaScriptArray, длина которого запрашивается. -
[out] result:uint32, представляющий длину массива.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API возвращает длину массива.
Array длина описана в разделе «Длина экземпляра массива» спецификации языка ECMAScript.
napi_get_arraybuffer_info
napi_status napi_get_arraybuffer_info(napi_env env,
napi_value arraybuffer,
void** data,
size_t* byte_length) copy -
[in] env: Среда, в которой вызывается API. -
[in] arraybuffer:napi_value, представляющий запрашиваемыйArrayBuffer. -
[out] data: Базовый буфер данныхArrayBuffer. Если byte_length равно0, это значение может бытьNULLили любым другим значением указателя. -
[out] byte_length: Длина базового буфера данных в байтах.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API используется для получения базового буфера данных ArrayBuffer и его длины.
ПРЕДУПРЕЖДЕНИЕ: Будьте осторожны при использовании этого API. Время жизни базового буфера данных управляется ArrayBuffer даже после его возврата. Один из возможных безопасных способов использования этого API — совместно с napi_create_reference, который можно использовать для гарантии контроля над временем жизни ArrayBuffer. Возвращенный буфер данных также безопасно использовать в рамках того же обратного вызова, если не вызываются другие API, которые могут запустить сборку мусора.
napi_get_buffer_info
napi_status napi_get_buffer_info(napi_env env,
napi_value value,
void** data,
size_t* length) copy -
[in] env: Среда, в которой вызывается API. -
[in] value:napi_value, представляющий запрашиваемыйnode::BufferилиUint8Array. -
[out] data: Базовый буфер данныхnode::BufferилиUint8Array. Если length равно0, это значение может бытьNULLили любым другим значением указателя. -
[out] length: Длина базового буфера данных в байтах.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот метод возвращает те же data и byte_length, что и napi_get_typedarray_info. Кроме того, napi_get_typedarray_info также принимает в качестве значения node::Buffer (Uint8Array).
Этот API используется для получения базового буфера данных node::Buffer и его длины.
Предупреждение: Будьте осторожны при использовании этого API, поскольку время жизни базового буфера данных не гарантируется, если им управляет виртуальная машина.
napi_get_prototype
napi_status napi_get_prototype(napi_env env,
napi_value object,
napi_value* result) copy -
[in] env: Среда, в которой вызывается API. -
[in] object:napi_value, представляющий объект JavaScriptObject, прототип которого нужно вернуть. Возвращается эквивалентObject.getPrototypeOf(это не то же самое, что свойствоprototypeфункции). -
[out] result:napi_value, представляющий прототип указанного объекта.
Возвращает napi_ok, если вызов API выполнен успешно.
napi_get_typedarray_info
napi_status napi_get_typedarray_info(napi_env env,
napi_value typedarray,
napi_typedarray_type* type,
size_t* length,
void** data,
napi_value* arraybuffer,
size_t* byte_offset) copy -
[in] env: Среда, в которой вызывается API. -
[in] typedarray:napi_value, представляющийTypedArray, свойства которого нужно запросить. -
[out] type: Скалярный тип данных элементов вTypedArray. -
[out] length: Количество элементов вTypedArray. -
[out] data: Буфер данных, лежащий в основеTypedArray, со смещениемbyte_offset, чтобы он указывал на первый элемент вTypedArray. Если длина массива равна0, это значение может бытьNULLили любым другим значением указателя. -
[out] arraybuffer:ArrayBuffer, лежащий в основеTypedArray. -
[out] byte_offset: Смещение в байтах внутри базового собственного массива, по которому находится первый элемент массива. Значение параметра data уже скорректировано так, чтобы data указывал на первый элемент массива. Поэтому первый байт собственного массива находился бы по адресуdata - byte_offset.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API возвращает различные свойства типизированного массива.
Для ненужных свойств соответствующие выходные параметры можно задать как NULL.
Предупреждение: Будьте осторожны при использовании этого API, поскольку базовым буфером данных управляет виртуальная машина.
napi_get_dataview_info
napi_status napi_get_dataview_info(napi_env env,
napi_value dataview,
size_t* byte_length,
void** data,
napi_value* arraybuffer,
size_t* byte_offset) copy -
[in] env: Среда, в которой вызывается API. -
[in] dataview:napi_value, представляющийDataView, свойства которого нужно запросить. -
[out] byte_length: Количество байтов вDataView. -
[out] data: Буфер данных, лежащий в основеDataView. Если byte_length равно0, это значение может бытьNULLили любым другим значением указателя. -
[out] arraybuffer:ArrayBuffer, лежащий в основеDataView. -
[out] byte_offset: Смещение в байтах внутри буфера данных, с которого начинается представлениеDataView.
Возвращает napi_ok, если вызов API выполнен успешно.
Для ненужных свойств соответствующие выходные параметры можно задать как NULL.
Этот API возвращает различные свойства DataView.
napi_get_date_value
napi_status napi_get_date_value(napi_env env,
napi_value value,
double* result) copy -
[in] env: Среда, в которой вызывается API. -
[in] value:napi_value, представляющий объект JavaScriptDate. -
[out] result: Значение времени типаdouble, представленное количеством миллисекунд, прошедших с полуночи 1 января 1970 года по UTC.
Этот API не учитывает високосные секунды: они игнорируются, поскольку ECMAScript соответствует спецификации времени POSIX.
Возвращает napi_ok, если вызов API выполнен успешно. Если передан объект napi_value, не являющийся датой, возвращается napi_date_expected.
Этот API возвращает примитивное значение типа double в C, соответствующее значению времени для указанного объекта JavaScript Date.
napi_get_value_bool
napi_status napi_get_value_bool(napi_env env, napi_value value, bool* result) copy
-
[in] env: Среда, в которой вызывается API. -
[in] value:napi_value, представляющий объект JavaScriptBoolean. -
[out] result: Примитивное логическое значение C, эквивалентное указанному объекту JavaScriptBoolean.
Возвращает napi_ok, если вызов API выполнен успешно. Если передан объект napi_value, не являющийся логическим значением, возвращается napi_boolean_expected.
Этот API возвращает примитивное логическое значение C, эквивалентное указанному объекту JavaScript Boolean.
napi_get_value_double
napi_status napi_get_value_double(napi_env env,
napi_value value,
double* result) copy -
[in] env: Среда, в которой вызывается API. -
[in] value:napi_value, представляющий объект JavaScriptnumber. -
[out] result: Примитивное значение типа double в C, эквивалентное указанному объекту JavaScriptnumber.
Возвращает napi_ok, если вызов API выполнен успешно. Если передан объект napi_value, не являющийся числом, возвращается napi_number_expected.
Этот API возвращает примитивное значение типа double в C, эквивалентное указанному объекту JavaScript number.
napi_get_value_bigint_int64
napi_status napi_get_value_bigint_int64(napi_env env,
napi_value value,
int64_t* result,
bool* lossless); copy -
[in] env: Среда, в которой вызывается API. -
[in] value:napi_value, представляющий объект JavaScriptBigInt. -
[out] result: Примитивное значение типа Cint64_t, эквивалентное указанному объекту JavaScriptBigInt. -
[out] lossless: Указывает, было ли значениеBigIntпреобразовано без потерь.
Возвращает napi_ok, если вызов API выполнен успешно. Если передан объект, не являющийся BigInt, возвращается napi_bigint_expected.
Этот API возвращает примитивное значение типа C int64_t, эквивалентное указанному объекту JavaScript BigInt. При необходимости значение будет усечено, а lossless будет установлено в false.
napi_get_value_bigint_uint64
napi_status napi_get_value_bigint_uint64(napi_env env,
napi_value value,
uint64_t* result,
bool* lossless); copy -
[in] env: Среда, в которой вызывается API. -
[in] value:napi_value, представляющий объект JavaScriptBigInt. -
[out] result: Примитивное значение типа Cuint64_t, эквивалентное указанному объекту JavaScriptBigInt. -
[out] lossless: Указывает, было ли значениеBigIntпреобразовано без потерь.
Возвращает napi_ok, если вызов API выполнен успешно. Если передан объект, не являющийся BigInt, возвращается napi_bigint_expected.
Этот API возвращает примитивное значение типа C uint64_t, эквивалентное указанному объекту JavaScript BigInt. При необходимости значение будет усечено, а lossless будет установлено в false.
napi_get_value_bigint_words
napi_status napi_get_value_bigint_words(napi_env env,
napi_value value,
int* sign_bit,
size_t* word_count,
uint64_t* words); copy -
[in] env: Среда, в которой вызывается API. -
[in] value:napi_value, представляющий объект JavaScriptBigInt. -
[out] sign_bit: Целое число, указывающее, является ли значение JavaScriptBigIntположительным или отрицательным. -
[in/out] word_count: Изначально должно содержать длину массиваwords. При возврате ему будет присвоено фактическое количество слов, необходимое для хранения этогоBigInt. -
[out] words: Указатель на предварительно выделенный массив 64-битных слов.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API преобразует одно значение BigInt в знаковый бит, массив 64-битных слов в порядке от младшего байта к старшему и количество элементов в массиве. Для получения только word_count значения sign_bit и words можно одновременно задать как NULL.
napi_get_value_external
napi_status napi_get_value_external(napi_env env,
napi_value value,
void** result) copy -
[in] env: Среда, в которой вызывается API. -
[in] value:napi_value, представляющий внешнее значение JavaScript. -
[out] result: Указатель на данные, обернутые во внешнее значение JavaScript.
Возвращает napi_ok, если вызов API выполнен успешно. Если передан объект napi_value, не являющийся внешним значением, возвращается napi_invalid_arg.
Этот API извлекает указатель на внешние данные, ранее переданный в napi_create_external().
napi_get_value_int32
napi_status napi_get_value_int32(napi_env env,
napi_value value,
int32_t* result) copy -
[in] env: Среда, в которой вызывается API. -
[in] value:napi_value, представляющий объект JavaScriptnumber. -
[out] result: Примитивное значение типа Cint32, эквивалентное указанному объекту JavaScriptnumber.
Возвращает napi_ok, если вызов API выполнен успешно. Если передан объект napi_value, не являющийся числом, возвращается napi_number_expected.
Этот API возвращает примитивное значение типа C int32, эквивалентное указанному объекту JavaScript number.
Если число выходит за диапазон 32-битного целого числа, результат усекается до соответствующего значения младших 32 бит. В результате большое положительное число может стать отрицательным, если значение > 231 - 1.
Для не конечных числовых значений (NaN, +Infinity или -Infinity) результат устанавливается в ноль.
napi_get_value_int64
napi_status napi_get_value_int64(napi_env env,
napi_value value,
int64_t* result) copy -
[in] env: Среда, в которой вызывается API. -
[in] value:napi_value, представляющий объект JavaScriptnumber. -
[out] result: Примитивное значение типа Cint64, эквивалентное указанному объекту JavaScriptnumber.
Возвращает napi_ok, если вызов API выполнен успешно. Если передан объект napi_value, не являющийся числом, возвращается napi_number_expected.
Этот API возвращает примитивное значение типа C int64, эквивалентное указанному объекту JavaScript number.
number Значения за пределами диапазона от Number.MIN_SAFE_INTEGER -(2**53 - 1) до Number.MAX_SAFE_INTEGER (2**53 - 1) теряют точность.
Для не конечных числовых значений (NaN, +Infinity или -Infinity) результат устанавливается в ноль.
napi_get_value_string_latin1
napi_status napi_get_value_string_latin1(napi_env env,
napi_value value,
char* buf,
size_t bufsize,
size_t* result) copy -
[in] env: Среда, в которой вызывается API. -
[in] value:napi_value, представляющий строку JavaScript. -
[in] buf: Буфер для записи строки в кодировке ISO-8859-1. Если переданоNULL, длина строки в байтах без завершающего нулевого символа возвращается вresult. -
[in] bufsize: Размер буфера назначения. Если этого значения недостаточно, возвращаемая строка усекается и завершается нулевым символом. Если значение равно нулю, строка не возвращается и буфер не изменяется. -
[out] result: Количество байтов, скопированных в буфер, без завершающего нулевого символа.
Возвращает napi_ok, если вызов API выполнен успешно. Если передан объект string napi_value, не являющийся строкой, возвращается napi_string_expected.
Этот API возвращает строку в кодировке ISO-8859-1, соответствующую переданному значению.
napi_get_value_string_utf8
napi_status napi_get_value_string_utf8(napi_env env,
napi_value value,
char* buf,
size_t bufsize,
size_t* result) copy -
[in] env: Среда, в которой вызывается API. -
[in] value:napi_value, представляющий строку JavaScript. -
[in] buf: Буфер для записи строки в кодировке UTF-8. Если переданоNULL, длина строки в байтах без завершающего нулевого символа возвращается вresult. -
[in] bufsize: Размер буфера назначения. Если этого значения недостаточно, возвращаемая строка усекается и завершается нулевым символом. Если значение равно нулю, строка не возвращается и буфер не изменяется. -
[out] result: Количество байтов, скопированных в буфер, без завершающего нулевого символа.
Возвращает napi_ok, если вызов API выполнен успешно. Если передан объект string napi_value, не являющийся строкой, возвращается napi_string_expected.
Этот API возвращает строку в кодировке UTF-8, соответствующую переданному значению.
napi_get_value_string_utf16
napi_status napi_get_value_string_utf16(napi_env env,
napi_value value,
char16_t* buf,
size_t bufsize,
size_t* result) copy -
[in] env: Среда, в которой вызывается API. -
[in] value:napi_value, представляющий строку JavaScript. -
[in] buf: Буфер для записи строки в кодировке UTF-16 LE. Если переданоNULL, длина строки в 2-байтовых кодовых единицах без завершающего нулевого символа возвращается. -
[in] bufsize: Размер буфера назначения. Если этого значения недостаточно, возвращаемая строка усекается и завершается нулевым символом. Если значение равно нулю, строка не возвращается и буфер не изменяется. -
[out] result: Количество 2-байтовых кодовых единиц, скопированных в буфер, без завершающего нулевого символа.
Возвращает napi_ok, если вызов API выполнен успешно. Если передан объект string napi_value, не являющийся строкой, возвращается napi_string_expected.
Этот API возвращает строку в кодировке UTF-16, соответствующую переданному значению.
napi_get_value_uint32
napi_status napi_get_value_uint32(napi_env env,
napi_value value,
uint32_t* result) copy -
[in] env: Среда, в которой вызывается API. -
[in] value:napi_value, представляющий объект JavaScriptnumber. -
[out] result: Примитивный тип C, эквивалентный указанномуnapi_valueв видеuint32_t.
Возвращает napi_ok, если вызов API выполнен успешно. Если передан объект napi_value, не являющийся числом, возвращается napi_number_expected.
Этот API возвращает примитивный тип C, эквивалентный указанному napi_value в виде uint32_t.
Функции для получения глобальных экземпляров
napi_get_boolean
napi_status napi_get_boolean(napi_env env, bool value, napi_value* result) copy
-
[in] env: Среда, в которой вызывается API. -
[in] value: Значение логического типа, которое нужно получить. -
[out] result:napi_value, представляющий одноэлементный объект JavaScriptBoolean, который нужно получить.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API используется для возврата одноэлементного объекта JavaScript, представляющего указанное логическое значение.
napi_get_global
napi_status napi_get_global(napi_env env, napi_value* result) copy
-
[in] env: Среда, в которой вызывается API. -
[out] result:napi_value, представляющий объект JavaScriptglobal.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API возвращает объект global.
napi_get_null
napi_status napi_get_null(napi_env env, napi_value* result) copy
-
[in] env: Среда, в которой вызывается API. -
[out] result:napi_value, представляющий объект JavaScriptnull.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API возвращает объект null.
napi_get_undefined
napi_status napi_get_undefined(napi_env env, napi_value* result) copy
-
[in] env: Среда, в которой вызывается API. -
[out] result:napi_value, представляющий значение JavaScript Undefined.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API возвращает объект Undefined.
Работа со значениями JavaScript и абстрактными операциями
Node-API предоставляет набор API для выполнения некоторых абстрактных операций над значениями JavaScript.
Эти API позволяют выполнять одно из следующих действий:
- Приводить значения JavaScript к определённым типам JavaScript (например,
numberилиstring). - Проверять тип значения JavaScript.
- Проверять равенство двух значений JavaScript.
napi_coerce_to_bool
napi_status napi_coerce_to_bool(napi_env env,
napi_value value,
napi_value* result) copy -
[in] env: среда, в которой вызывается API. -
[in] value: значение JavaScript для приведения. -
[out] result:napi_value, представляющий приведённыйBooleanJavaScript.
Возвращает napi_ok, если API выполнен успешно.
Этот API реализует абстрактную операцию ToBoolean(), определённую в разделе ToBoolean спецификации языка ECMAScript.
napi_coerce_to_number
napi_status napi_coerce_to_number(napi_env env,
napi_value value,
napi_value* result) copy -
[in] env: среда, в которой вызывается API. -
[in] value: значение JavaScript для приведения. -
[out] result:napi_value, представляющий приведённыйnumberJavaScript.
Возвращает napi_ok, если API выполнен успешно.
Этот API реализует абстрактную операцию ToNumber(), определённую в разделе ToNumber спецификации языка ECMAScript. Если переданное значение является объектом, эта функция может выполнить код JS.
napi_coerce_to_object
napi_status napi_coerce_to_object(napi_env env,
napi_value value,
napi_value* result) copy -
[in] env: среда, в которой вызывается API. -
[in] value: значение JavaScript для приведения. -
[out] result:napi_value, представляющий приведённыйObjectJavaScript.
Возвращает napi_ok, если API выполнен успешно.
Этот API реализует абстрактную операцию ToObject(), определённую в разделе ToObject спецификации языка ECMAScript.
napi_coerce_to_string
napi_status napi_coerce_to_string(napi_env env,
napi_value value,
napi_value* result) copy -
[in] env: среда, в которой вызывается API. -
[in] value: значение JavaScript для приведения. -
[out] result:napi_value, представляющий приведённыйstringJavaScript.
Возвращает napi_ok, если API выполнен успешно.
Этот API реализует абстрактную операцию ToString(), определённую в разделе ToString спецификации языка ECMAScript. Если переданное значение является объектом, эта функция может выполнить код JS.
napi_typeof
napi_status napi_typeof(napi_env env, napi_value value, napi_valuetype* result) copy
-
[in] env: среда, в которой вызывается API. -
[in] value: значение JavaScript, тип которого нужно определить. -
[out] result: тип значения JavaScript.
Возвращает napi_ok, если API выполнен успешно.
-
napi_invalid_arg, если типvalueне является известным типом ECMAScript иvalueне является значением External.
Этот API обеспечивает поведение, аналогичное применению оператора typeof к объекту, как определено в разделе «Оператор typeof» спецификации языка ECMAScript. Однако есть несколько отличий:
- Поддерживается обнаружение значения External.
- Тип
nullопределяется отдельно, тогда как оператор ECMAScripttypeofопределил быobject.
Если тип value недопустим, возвращается ошибка.
napi_instanceof
napi_status napi_instanceof(napi_env env,
napi_value object,
napi_value constructor,
bool* result) copy -
[in] env: среда, в которой вызывается API. -
[in] object: проверяемое значение JavaScript. -
[in] constructor: объект-функция JavaScript — функция-конструктор, с которой выполняется сравнение. -
[out] result: логическое значение, которому присваивается true, еслиobject instanceof constructorравно true.
Возвращает napi_ok, если API выполнен успешно.
Этот API соответствует применению оператора instanceof к объекту, как определено в разделе «Оператор instanceof» спецификации языка ECMAScript.
napi_is_array
napi_status napi_is_array(napi_env env, napi_value value, bool* result) copy
-
[in] env: среда, в которой вызывается API. -
[in] value: проверяемое значение JavaScript. -
[out] result: является ли данный объект массивом.
Возвращает napi_ok, если API выполнен успешно.
Этот API соответствует применению операции IsArray к объекту, как определено в разделе IsArray спецификации языка ECMAScript.
napi_is_arraybuffer
napi_status napi_is_arraybuffer(napi_env env, napi_value value, bool* result) copy
-
[in] env: среда, в которой вызывается API. -
[in] value: проверяемое значение JavaScript. -
[out] result: является ли данный объектArrayBuffer.
Возвращает napi_ok, если API выполнен успешно.
Этот API проверяет, является ли переданный Object буфером массива.
napi_is_buffer
napi_status napi_is_buffer(napi_env env, napi_value value, bool* result) copy
-
[in] env: среда, в которой вызывается API. -
[in] value: проверяемое значение JavaScript. -
[out] result: представляет ли данныйnapi_valueобъект типаnode::BufferилиUint8Array.
Возвращает napi_ok, если API выполнен успешно.
Этот API проверяет, является ли переданный Object буфером или Uint8Array. Если вызывающей стороне нужно проверить, является ли значение Uint8Array, следует предпочесть napi_is_typedarray.
napi_is_date
napi_status napi_is_date(napi_env env, napi_value value, bool* result) copy
-
[in] env: среда, в которой вызывается API. -
[in] value: проверяемое значение JavaScript. -
[out] result: представляет ли данныйnapi_valueобъект JavaScript типаDate.
Возвращает napi_ok, если API выполнен успешно.
Этот API проверяет, является ли переданный Object датой.
napi_is_error
napi_status napi_is_error(napi_env env, napi_value value, bool* result) copy
-
[in] env: среда, в которой вызывается API. -
[in] value: проверяемое значение JavaScript. -
[out] result: представляет ли данныйnapi_valueобъект типаError.
Возвращает napi_ok, если API выполнен успешно.
Этот API проверяет, является ли переданный Object значением типа Error.
napi_is_typedarray
napi_status napi_is_typedarray(napi_env env, napi_value value, bool* result) copy
-
[in] env: среда, в которой вызывается API. -
[in] value: проверяемое значение JavaScript. -
[out] result: представляет ли данныйnapi_valueобъект типаTypedArray.
Возвращает napi_ok, если API выполнен успешно.
Этот API проверяет, является ли переданный Object типизированным массивом.
napi_is_dataview
napi_status napi_is_dataview(napi_env env, napi_value value, bool* result) copy
-
[in] env: среда, в которой вызывается API. -
[in] value: проверяемое значение JavaScript. -
[out] result: представляет ли данныйnapi_valueобъект типаDataView.
Возвращает napi_ok, если API выполнен успешно.
Этот API проверяет, является ли переданный Object объектом типа DataView.
napi_strict_equals
napi_status napi_strict_equals(napi_env env,
napi_value lhs,
napi_value rhs,
bool* result) copy -
[in] env: среда, в которой вызывается API. -
[in] lhs: проверяемое значение JavaScript. -
[in] rhs: значение JavaScript для сравнения. -
[out] result: равны ли два объектаnapi_value.
Возвращает napi_ok, если API выполнен успешно.
Этот API соответствует выполнению алгоритма строгого равенства, определённого в разделе IsStrctEqual спецификации языка ECMAScript.
napi_detach_arraybuffer
napi_status napi_detach_arraybuffer(napi_env env,
napi_value arraybuffer) copy -
[in] env: среда, в которой вызывается API. -
[in] arraybuffer: JavaScript-ArrayBuffer, которое нужно отсоединить.
Возвращает napi_ok, если API выполнен успешно. Если передано неотсоединяемое ArrayBuffer, возвращается napi_detachable_arraybuffer_expected.
Как правило, ArrayBuffer нельзя отсоединить, если оно уже было отсоединено. Движок может накладывать дополнительные условия на возможность отсоединения ArrayBuffer. Например, для V8 требуется, чтобы ArrayBuffer было внешним, то есть созданным с помощью napi_create_external_arraybuffer.
Этот API соответствует выполнению операции отсоединения ArrayBuffer, определённой в разделе detachArrayBuffer спецификации языка ECMAScript.
napi_is_detached_arraybuffer
napi_status napi_is_detached_arraybuffer(napi_env env,
napi_value arraybuffer,
bool* result) copy -
[in] env: среда, в которой вызывается API. -
[in] arraybuffer: JavaScript-ArrayBuffer, которое нужно проверить. -
[out] result: отсоединено лиarraybuffer.
Возвращает napi_ok, если API выполнен успешно.
Считается, что ArrayBuffer отсоединено, если его внутренние данные равны null.
Этот API соответствует выполнению операции ArrayBuffer IsDetachedBuffer, определённой в разделе isDetachedBuffer спецификации языка ECMAScript.
Работа со свойствами JavaScript
Node-API предоставляет набор API для получения и установки свойств объектов JavaScript.
Свойства в JavaScript представлены парой из ключа и значения. По сути, все ключи свойств в Node-API могут быть представлены в одной из следующих форм:
- Именованные: простая строка в кодировке UTF-8
- Индексированные целыми числами: значение индекса, представленное с помощью
uint32_t - Значение JavaScript: в Node-API они представлены с помощью
napi_value. Это может бытьnapi_value, представляющийstring,numberилиsymbol.
Значения Node-API представлены типом napi_value. Любой вызов Node-API, которому требуется значение JavaScript, принимает napi_value. Однако вызывающий код должен убедиться, что соответствующий napi_value имеет тип JavaScript, ожидаемый API.
API, описанные в этом разделе, предоставляют простой интерфейс для получения и установки свойств произвольных объектов JavaScript, представленных с помощью napi_value.
Например, рассмотрим следующий фрагмент кода JavaScript:
const obj = {};
obj.myProp = 123; copy Эквивалентный код с использованием значений Node-API может выглядеть так:
napi_status status = napi_generic_failure;
// const obj = {}
napi_value obj, value;
status = napi_create_object(env, &obj);
if (status != napi_ok) return status;
// Create a napi_value for 123
status = napi_create_int32(env, 123, &value);
if (status != napi_ok) return status;
// obj.myProp = 123
status = napi_set_named_property(env, obj, "myProp", value);
if (status != napi_ok) return status; copy Индексированные свойства можно устанавливать аналогичным образом. Рассмотрим следующий фрагмент кода JavaScript:
const arr = []; arr[123] = 'hello'; copy
Эквивалентный код с использованием значений Node-API может выглядеть так:
napi_status status = napi_generic_failure; // const arr = []; napi_value arr, value; status = napi_create_array(env, &arr); if (status != napi_ok) return status; // Create a napi_value for 'hello' status = napi_create_string_utf8(env, "hello", NAPI_AUTO_LENGTH, &value); if (status != napi_ok) return status; // arr[123] = 'hello'; status = napi_set_element(env, arr, 123, value); if (status != napi_ok) return status; copy
Свойства можно получать с помощью API, описанных в этом разделе. Рассмотрим следующий фрагмент кода JavaScript:
const arr = []; const value = arr[123]; copy
Приблизительный эквивалент на Node-API выглядит так:
napi_status status = napi_generic_failure; // const arr = [] napi_value arr, value; status = napi_create_array(env, &arr); if (status != napi_ok) return status; // const value = arr[123] status = napi_get_element(env, arr, 123, &value); if (status != napi_ok) return status; copy
Наконец, для повышения производительности на объекте можно также определить несколько свойств. Рассмотрим следующий код JavaScript:
const obj = {};
Object.defineProperties(obj, {
'foo': { value: 123, writable: true, configurable: true, enumerable: true },
'bar': { value: 456, writable: true, configurable: true, enumerable: true },
}); copy Приблизительный эквивалент на Node-API выглядит так:
napi_status status = napi_status_generic_failure;
// const obj = {};
napi_value obj;
status = napi_create_object(env, &obj);
if (status != napi_ok) return status;
// Create napi_values for 123 and 456
napi_value fooValue, barValue;
status = napi_create_int32(env, 123, &fooValue);
if (status != napi_ok) return status;
status = napi_create_int32(env, 456, &barValue);
if (status != napi_ok) return status;
// Set the properties
napi_property_descriptor descriptors[] = {
{ "foo", NULL, NULL, NULL, NULL, fooValue, napi_writable | napi_configurable, NULL },
{ "bar", NULL, NULL, NULL, NULL, barValue, napi_writable | napi_configurable, NULL }
}
status = napi_define_properties(env,
obj,
sizeof(descriptors) / sizeof(descriptors[0]),
descriptors);
if (status != napi_ok) return status; copy Структуры
napi_property_attributes
typedef enum {
napi_default = 0,
napi_writable = 1 << 0,
napi_enumerable = 1 << 1,
napi_configurable = 1 << 2,
// Used with napi_define_class to distinguish static properties
// from instance properties. Ignored by napi_define_properties.
napi_static = 1 << 10,
// Default for class methods.
napi_default_method = napi_writable | napi_configurable,
// Default for object properties, like in JS obj[prop].
napi_default_jsproperty = napi_writable |
napi_enumerable |
napi_configurable,
} napi_property_attributes; copy napi_property_attributes — это битовые флаги, управляющие поведением свойств, устанавливаемых для объекта JavaScript. За исключением napi_static, они соответствуют атрибутам, перечисленным в разделе «Атрибуты свойств» спецификации языка ECMAScript. Это могут быть один или несколько следующих битовых флагов:
-
napi_default: для свойства не заданы явные атрибуты. По умолчанию свойство доступно только для чтения, не перечисляется и не настраивается. -
napi_writable: свойство доступно для записи. -
napi_enumerable: свойство перечисляется. -
napi_configurable: свойство можно настроить, как определено в разделе «Атрибуты свойств» спецификации языка ECMAScript. -
napi_static: свойство будет определено как статическое свойство класса, а не как свойство экземпляра, используемое по умолчанию. Используется только вnapi_define_class. Игнорируетсяnapi_define_properties. -
napi_default_method: подобно методу в классе JS, свойство можно настроить и записать, но оно не перечисляется. -
napi_default_jsproperty: подобно свойству, заданному с помощью присваивания в JavaScript, свойство доступно для записи, перечисляется и настраивается.
napi_property_descriptor
typedef struct {
// One of utf8name or name should be NULL.
const char* utf8name;
napi_value name;
napi_callback method;
napi_callback getter;
napi_callback setter;
napi_value value;
napi_property_attributes attributes;
void* data;
} napi_property_descriptor; copy -
utf8name: Необязательная строка с описанием ключа свойства в кодировке UTF-8. Для свойства необходимо указать либоutf8name, либоname. -
name: Необязательныйnapi_value, указывающий на строку JavaScript или символ, который будет использоваться в качестве ключа свойства. Для свойства необходимо указать либоutf8name, либоname. -
value: Значение, возвращаемое при чтении свойства, если оно является свойством данных. Если этот параметр задан, установитеgetter,setter,methodиdataвNULL, поскольку эти элементы не будут использоваться. -
getter: Функция, вызываемая при чтении свойства. Если этот параметр задан, установитеvalueиmethodвNULL, поскольку эти элементы не будут использоваться. Среда выполнения неявно вызывает указанную функцию при обращении к свойству из кода JavaScript (или при чтении свойства с помощью вызова Node-API). Дополнительные сведения приведены вnapi_callback. -
setter: Функция, вызываемая при записи свойства. Если этот параметр задан, установитеvalueиmethodвNULL, поскольку эти элементы не будут использоваться. Среда выполнения неявно вызывает указанную функцию при установке свойства из кода JavaScript (или при записи свойства с помощью вызова Node-API). Дополнительные сведения приведены вnapi_callback. -
method: Задайте этот параметр, чтобы свойствоvalueобъекта дескриптора свойства было функцией JavaScript, представленнойmethod. Если этот параметр задан, установитеvalue,getterиsetterвNULL, поскольку эти элементы не будут использоваться. Дополнительные сведения приведены вnapi_callback. -
attributes: Атрибуты, связанные с конкретным свойством. См.napi_property_attributes. -
data: Данные обратного вызова, передаваемые вmethod,getterиsetterпри вызове этой функции.
Функции
napi_get_property_names
napi_status napi_get_property_names(napi_env env,
napi_value object,
napi_value* result); copy -
[in] env: Среда, в которой вызывается Node-API. -
[in] object: Объект, свойства которого нужно получить. -
[out] result:napi_value, представляющий массив значений JavaScript, соответствующих именам свойств объекта. Для перебора элементовresultможно использоватьnapi_get_array_lengthиnapi_get_element.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API возвращает имена перечисляемых свойств object в виде массива строк. Свойства object с ключом-символом не включаются.
napi_get_all_property_names
napi_get_all_property_names(napi_env env,
napi_value object,
napi_key_collection_mode key_mode,
napi_key_filter key_filter,
napi_key_conversion key_conversion,
napi_value* result); copy -
[in] env: Среда, в которой вызывается Node-API. -
[in] object: Объект, свойства которого нужно получить. -
[in] key_mode: Следует ли также получать свойства прототипа. -
[in] key_filter: Какие свойства нужно получить (перечисляемые/доступные для чтения/доступные для записи). -
[in] key_conversion: Следует ли преобразовывать числовые ключи свойств в строки. -
[out] result:napi_value, представляющий массив значений JavaScript, соответствующих именам свойств объекта. Для перебора элементовresultможно использоватьnapi_get_array_lengthиnapi_get_element.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API возвращает массив, содержащий имена доступных свойств данного объекта.
napi_set_property
napi_status napi_set_property(napi_env env,
napi_value object,
napi_value key,
napi_value value); copy -
[in] env: Среда, в которой вызывается Node-API. -
[in] object: Объект, которому нужно задать свойство. -
[in] key: Имя задаваемого свойства. -
[in] value: Значение свойства.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API задаёт свойство для переданного Object.
napi_get_property
napi_status napi_get_property(napi_env env,
napi_value object,
napi_value key,
napi_value* result); copy -
[in] env: Среда, в которой вызывается Node-API. -
[in] object: Объект, из которого нужно получить свойство. -
[in] key: Имя получаемого свойства. -
[out] result: Значение свойства.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API получает запрошенное свойство из переданного Object.
napi_has_property
napi_status napi_has_property(napi_env env,
napi_value object,
napi_value key,
bool* result); copy -
[in] env: Среда, в которой вызывается Node-API. -
[in] object: Объект для проверки. -
[in] key: Имя свойства, наличие которого нужно проверить. -
[out] result: Существует ли свойство объекта.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API проверяет, содержит ли переданный Object именованное свойство.
napi_delete_property
napi_status napi_delete_property(napi_env env,
napi_value object,
napi_value key,
bool* result); copy -
[in] env: Среда, в которой вызывается Node-API. -
[in] object: Объект для проверки. -
[in] key: Имя удаляемого свойства. -
[out] result: Удалось ли удалить свойство. Параметрresultможно не указывать, передавNULL.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API пытается удалить собственное свойство key из object.
napi_has_own_property
napi_status napi_has_own_property(napi_env env,
napi_value object,
napi_value key,
bool* result); copy -
[in] env: Среда, в которой вызывается Node-API. -
[in] object: Объект для проверки. -
[in] key: Имя собственного свойства, наличие которого нужно проверить. -
[out] result: Существует ли собственное свойство объекта.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API проверяет, содержит ли переданный Object указанное собственное свойство. key должен быть string или symbol, иначе будет выброшена ошибка. Node-API не выполняет преобразование типов данных.
napi_set_named_property
napi_status napi_set_named_property(napi_env env,
napi_value object,
const char* utf8Name,
napi_value value); copy -
[in] env: Среда, в которой вызывается Node-API. -
[in] object: Объект, которому нужно задать свойство. -
[in] utf8Name: Имя задаваемого свойства. -
[in] value: Значение свойства.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот метод эквивалентен вызову napi_set_property с napi_value, созданным из строки, переданной как utf8Name.
napi_get_named_property
napi_status napi_get_named_property(napi_env env,
napi_value object,
const char* utf8Name,
napi_value* result); copy -
[in] env: Среда, в которой вызывается Node-API. -
[in] object: Объект, из которого нужно получить свойство. -
[in] utf8Name: Имя получаемого свойства. -
[out] result: Значение свойства.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот метод эквивалентен вызову napi_get_property с napi_value, созданным из строки, переданной как utf8Name.
napi_has_named_property
napi_status napi_has_named_property(napi_env env,
napi_value object,
const char* utf8Name,
bool* result); copy -
[in] env: Среда, в которой вызывается Node-API. -
[in] object: Объект для проверки. -
[in] utf8Name: Имя свойства, наличие которого нужно проверить. -
[out] result: Существует ли свойство объекта.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот метод эквивалентен вызову napi_has_property с napi_value, созданным из строки, переданной как utf8Name.
napi_set_element
napi_status napi_set_element(napi_env env,
napi_value object,
uint32_t index,
napi_value value); copy -
[in] env: Среда, в которой вызывается Node-API. -
[in] object: Объект, которому нужно задать свойства. -
[in] index: Индекс задаваемого свойства. -
[in] value: Значение свойства.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API задаёт элемент для переданного Object.
napi_get_element
napi_status napi_get_element(napi_env env,
napi_value object,
uint32_t index,
napi_value* result); copy -
[in] env: Среда, в которой вызывается Node-API. -
[in] object: Объект, из которого нужно получить свойство. -
[in] index: Индекс получаемого свойства. -
[out] result: Значение свойства.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API получает элемент по указанному индексу.
napi_has_element
napi_status napi_has_element(napi_env env,
napi_value object,
uint32_t index,
bool* result); copy -
[in] env: Среда, в которой вызывается Node-API. -
[in] object: Объект для проверки. -
[in] index: Индекс свойства, наличие которого нужно проверить. -
[out] result: Существует ли свойство объекта.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API сообщает, содержит ли переданный Object элемент по указанному индексу.
napi_delete_element
napi_status napi_delete_element(napi_env env,
napi_value object,
uint32_t index,
bool* result); copy -
[in] env: Среда, в которой вызывается Node-API. -
[in] object: Объект для проверки. -
[in] index: Индекс удаляемого свойства. -
[out] result: Удалось ли удалить элемент. Параметрresultможно не указывать, передавNULL.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API пытается удалить указанный index из object.
napi_define_properties
napi_status napi_define_properties(napi_env env,
napi_value object,
size_t property_count,
const napi_property_descriptor* properties); copy -
[in] env: Среда, в которой вызывается Node-API. -
[in] object: Объект, для которого нужно определить свойства. -
[in] property_count: Количество элементов в массивеproperties. -
[in] properties: Массив дескрипторов свойств.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот метод позволяет эффективно определять несколько свойств для заданного объекта. Свойства определяются с помощью дескрипторов свойств (см. napi_property_descriptor). Получив массив таких дескрипторов свойств, этот API устанавливает свойства объекта по одному в соответствии с DefineOwnProperty() (описанным в разделе «DefineOwnProperty» спецификации ECMA-262).
napi_object_freeze
napi_status napi_object_freeze(napi_env env,
napi_value object); copy -
[in] env: Среда, в которой вызывается Node-API. -
[in] object: Объект, который нужно заморозить.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот метод замораживает заданный объект. Он запрещает добавлять новые свойства, удалять существующие, изменять перечисляемость, настраиваемость или возможность записи существующих свойств, а также изменять значения существующих свойств. Кроме того, он запрещает изменять прототип объекта. Это описано в разделе 19.1.2.6 спецификации ECMA-262.
napi_object_seal
napi_status napi_object_seal(napi_env env,
napi_value object); copy -
[in] env: Среда, в которой вызывается Node-API. -
[in] object: Объект, который нужно запечатать.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот метод запечатывает заданный объект. Он запрещает добавлять новые свойства и помечает все существующие свойства как ненастраиваемые. Это описано в разделе 19.1.2.20 спецификации ECMA-262.
Работа с функциями JavaScript
Node-API предоставляет набор API, позволяющих коду JavaScript вызывать собственный код. Node-API, поддерживающие вызов собственного кода, принимают функцию обратного вызова, представленную типом napi_callback. Когда виртуальная машина JavaScript вызывает собственный код, выполняется предоставленная функция napi_callback. API, описанные в этом разделе, позволяют функции обратного вызова выполнять следующие действия:
- Получать сведения о контексте, в котором была вызвана функция обратного вызова.
- Получать аргументы, переданные функции обратного вызова.
- Возвращать из функции обратного вызова значение
napi_value.
Кроме того, Node-API предоставляет набор функций, позволяющих вызывать функции JavaScript из собственного кода. Функцию можно вызвать как обычную функцию JavaScript или как функцию-конструктор.
Любые данные, отличные от NULL, переданные этому API через поле data элементов napi_property_descriptor, можно связать с object и освободить после сборки мусора для object, передав и object, и данные в napi_add_finalizer.
napi_call_function
NAPI_EXTERN napi_status napi_call_function(napi_env env,
napi_value recv,
napi_value func,
size_t argc,
const napi_value* argv,
napi_value* result); copy -
[in] env: Среда, в которой вызывается API. -
[in] recv: Значениеthis, передаваемое вызываемой функции. -
[in] func:napi_value, представляющий вызываемую функцию JavaScript. -
[in] argc: Количество элементов в массивеargv. -
[in] argv: Массив объектовnapi_values, представляющих значения JavaScript, передаваемые функции в качестве аргументов. -
[out] result:napi_value, представляющий возвращённый объект JavaScript.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот метод позволяет вызывать объект функции JavaScript из собственного дополнения. Это основной механизм вызова JavaScript из собственного кода дополнения. О специальном случае вызова JavaScript после асинхронной операции см. napi_make_callback.
Пример использования может выглядеть следующим образом. Рассмотрим фрагмент кода JavaScript:
function AddTwo(num) {
return num + 2;
}
global.AddTwo = AddTwo; copy Затем приведённую выше функцию можно вызвать из собственного дополнения с помощью следующего кода:
// Get the function named "AddTwo" on the global object napi_value global, add_two, arg; napi_status status = napi_get_global(env, &global); if (status != napi_ok) return; status = napi_get_named_property(env, global, "AddTwo", &add_two); if (status != napi_ok) return; // const arg = 1337 status = napi_create_int32(env, 1337, &arg); if (status != napi_ok) return; napi_value* argv = &arg; size_t argc = 1; // AddTwo(arg); napi_value return_val; status = napi_call_function(env, global, add_two, argc, argv, &return_val); if (status != napi_ok) return; // Convert the result back to a native type int32_t result; status = napi_get_value_int32(env, return_val, &result); if (status != napi_ok) return; copy
napi_create_function
napi_status napi_create_function(napi_env env,
const char* utf8name,
size_t length,
napi_callback cb,
void* data,
napi_value* result); copy -
[in] env: Среда, в которой вызывается API. -
[in] utf8Name: Необязательное имя функции в кодировке UTF-8. В JavaScript оно отображается как свойствоnameнового объекта функции. -
[in] length: Длинаutf8nameв байтах илиNAPI_AUTO_LENGTH, если строка завершается нулевым символом. -
[in] cb: Собственная функция, вызываемая при вызове этого объекта функции. Дополнительные сведения приведены вnapi_callback. -
[in] data: Предоставленные пользователем контекстные данные. Они будут переданы обратно функции при её последующем вызове. -
[out] result:napi_value, представляющий объект JavaScript для созданной функции.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API позволяет автору дополнения создать объект функции в собственном коде. Это основной механизм вызова собственного кода дополнения из JavaScript.
После этого вызова созданная функция автоматически не становится доступной из скрипта. Чтобы к функции можно было обратиться из скрипта, необходимо явно задать её свойством объекта, доступного JavaScript.
Чтобы экспортировать функцию как часть экспортируемых модулем дополнения значений, задайте созданную функцию свойством объекта exports. Пример модуля может выглядеть следующим образом:
napi_value SayHello(napi_env env, napi_callback_info info) {
printf("Hello\n");
return NULL;
}
napi_value Init(napi_env env, napi_value exports) {
napi_status status;
napi_value fn;
status = napi_create_function(env, NULL, 0, SayHello, NULL, &fn);
if (status != napi_ok) return NULL;
status = napi_set_named_property(env, exports, "sayHello", fn);
if (status != napi_ok) return NULL;
return exports;
}
NAPI_MODULE(NODE_GYP_MODULE_NAME, Init) copy С приведённым выше кодом дополнение можно использовать в JavaScript следующим образом:
const myaddon = require('./addon');
myaddon.sayHello(); copy Строка, переданная в require(), — это имя целевого объекта в binding.gyp, отвечающего за создание файла .node.
Любые данные, отличные от NULL, переданные этому API через параметр data, можно связать с результирующей функцией JavaScript (возвращаемой в параметре result) и освободить после сборки мусора для функции, передав и функцию JavaScript, и данные в napi_add_finalizer.
Функции JavaScript Function описаны в разделе «Объекты-функции» спецификации языка ECMAScript.
napi_get_cb_info
napi_status napi_get_cb_info(napi_env env,
napi_callback_info cbinfo,
size_t* argc,
napi_value* argv,
napi_value* thisArg,
void** data) copy -
[in] env: Среда, в которой вызывается API. -
[in] cbinfo: Информация обратного вызова, переданная функции обратного вызова. -
[in-out] argc: Задаёт длину предоставленного массиваargvи получает фактическое количество аргументов. Параметрargcможно не указывать, передавNULL. -
[out] argv: Массив C из объектовnapi_value, в который копируются аргументы. Если аргументов больше, чем указано, копируется только запрошенное количество. Если аргументов меньше, чем указано, оставшаяся частьargvзаполняется значениямиnapi_value, представляющимиundefined. Параметрargvможно не указывать, передавNULL. -
[out] thisArg: Получает аргумент JavaScriptthisдля вызова. ПараметрthisArgможно не указывать, передавNULL. -
[out] data: Получает указатель на данные для функции обратного вызова. Параметрdataможно не указывать, передавNULL.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот метод используется внутри функции обратного вызова для получения сведений о вызове, таких как аргументы и указатель this, из заданной информации обратного вызова.
napi_get_new_target
napi_status napi_get_new_target(napi_env env,
napi_callback_info cbinfo,
napi_value* result) copy -
[in] env: Среда, в которой вызывается API. -
[in] cbinfo: Информация обратного вызова, переданная функции обратного вызова. -
[out] result:new.targetвызова конструктора.
Возвращает napi_ok, если вызов API выполнен успешно.
Этот API возвращает new.target вызова конструктора. Если текущий обратный вызов не является вызовом конструктора, результатом будет NULL.
napi_new_instance
napi_status napi_new_instance(napi_env env,
napi_value cons,
size_t argc,
napi_value* argv,
napi_value* result) copy -
[in] env: Среда, в которой вызывается API. -
[in] cons:napi_value, представляющий функцию JavaScript, вызываемую в качестве конструктора. -
[in] argc: Количество элементов в массивеargv. -
[in] argv: Массив значений JavaScript в виде объектовnapi_value, представляющих аргументы конструктора. Еслиargcравно нулю, этот параметр можно опустить, передавNULL. -
[out] result:napi_value, представляющий возвращённый объект JavaScript, который в данном случае является созданным объектом.
Этот метод используется для создания нового значения JavaScript с помощью заданного napi_value, представляющего конструктор объекта. Например, рассмотрим следующий фрагмент кода:
function MyObject(param) {
this.param = param;
}
const arg = 'hello';
const value = new MyObject(arg); copy В Node-API приведённый ниже код позволяет получить приблизительный эквивалент:
// Get the constructor function MyObject napi_value global, constructor, arg, value; napi_status status = napi_get_global(env, &global); if (status != napi_ok) return; status = napi_get_named_property(env, global, "MyObject", &constructor); if (status != napi_ok) return; // const arg = "hello" status = napi_create_string_utf8(env, "hello", NAPI_AUTO_LENGTH, &arg); if (status != napi_ok) return; napi_value* argv = &arg; size_t argc = 1; // const value = new MyObject(arg) status = napi_new_instance(env, constructor, argc, argv, &value); copy
Возвращает napi_ok, если вызов API выполнен успешно.
Обёртывание объектов
Node-API позволяет «оборачивать» классы и экземпляры C++, чтобы конструктор и методы класса можно было вызывать из JavaScript.
- API
napi_define_classопределяет класс JavaScript с конструктором, статическими свойствами и методами, а также свойствами и методами экземпляра, соответствующими классу C++. - Когда код JavaScript вызывает конструктор, функция обратного вызова конструктора использует
napi_wrap, чтобы обернуть новый экземпляр C++ в объект JavaScript, а затем возвращает объект-обёртку. - Когда код JavaScript вызывает метод или метод доступа к свойству класса, вызывается соответствующая функция C++
napi_callback. Для обратного вызова экземпляра функцияnapi_unwrapполучает экземпляр C++, являющийся объектом вызова.
Для обёрнутых объектов может быть сложно различить функцию, вызванную для прототипа класса, и функцию, вызванную для экземпляра класса. Распространённый способ решения этой проблемы — сохранить постоянную ссылку на конструктор класса для последующих проверок instanceof.
napi_value MyClass_constructor = NULL;
status = napi_get_reference_value(env, MyClass::es_constructor, &MyClass_constructor);
assert(napi_ok == status);
bool is_instance = false;
status = napi_instanceof(env, es_this, MyClass_constructor, &is_instance);
assert(napi_ok == status);
if (is_instance) {
// napi_unwrap() ...
} else {
// otherwise...
} copy Ссылку необходимо освободить, когда она больше не нужна.
В некоторых случаях napi_instanceof() недостаточно, чтобы гарантировать, что объект JavaScript является обёрткой определённого собственного типа. Особенно это касается случаев, когда обёрнутые объекты JavaScript передаются обратно в аддон через статические методы, а не как значение this методов прототипа. В таких случаях существует вероятность, что объекты будут развёрнуты некорректно.
const myAddon = require('./build/Release/my_addon.node');
// `openDatabase()` returns a JavaScript object that wraps a native database
// handle.
const dbHandle = myAddon.openDatabase();
// `query()` returns a JavaScript object that wraps a native query handle.
const queryHandle = myAddon.query(dbHandle, 'Gimme ALL the things!');
// There is an accidental error in the line below. The first parameter to
// `myAddon.queryHasRecords()` should be the database handle (`dbHandle`), not
// the query handle (`query`), so the correct condition for the while-loop
// should be
//
// myAddon.queryHasRecords(dbHandle, queryHandle)
//
while (myAddon.queryHasRecords(queryHandle, dbHandle)) {
// retrieve records
} copy В приведённом выше примере myAddon.queryHasRecords() — это метод, принимающий два аргумента. Первый — дескриптор базы данных, второй — дескриптор запроса. Внутри метода первый аргумент разворачивается, а полученный указатель преобразуется к типу собственного дескриптора базы данных. Затем разворачивается второй аргумент, а полученный указатель преобразуется к типу дескриптора запроса. Если аргументы переданы в неправильном порядке, преобразования выполнятся, однако базовая операция с базой данных, вероятно, завершится ошибкой или даже приведёт к недопустимому обращению к памяти.
Чтобы убедиться, что указатель, полученный из первого аргумента, действительно указывает на дескриптор базы данных, а указатель, полученный из второго аргумента, — на дескриптор запроса, реализация queryHasRecords() должна выполнить проверку типа. Сохранение конструктора класса JavaScript, экземпляром которого был создан дескриптор базы данных, и конструктора, экземпляром которого был создан дескриптор запроса, в napi_ref может помочь, поскольку тогда можно использовать napi_instanceof(), чтобы убедиться, что экземпляры, переданные в queryHashRecords(), действительно имеют правильный тип.
К сожалению, napi_instanceof() не защищает от изменения прототипа. Например, прототип экземпляра дескриптора базы данных можно установить в прототип конструктора экземпляров дескриптора запроса. В этом случае экземпляр дескриптора базы данных может выглядеть как экземпляр дескриптора запроса и пройти проверку napi_instanceof() для экземпляра дескриптора запроса, при этом по-прежнему содержать указатель на дескриптор базы данных.
Для этого Node-API предоставляет возможность присваивать типовые метки.
Типовая метка — это 128-битное целое число, уникальное для аддона. Node-API предоставляет структуру napi_type_tag для хранения типовой метки. Если такое значение передаётся вместе с объектом JavaScript или внешним объектом, хранящимся в napi_value, в napi_type_tag_object(), объект JavaScript будет «помечен» типовой меткой. Эта «метка» невидима со стороны JavaScript. Когда объект JavaScript поступает в собственную привязку, napi_check_object_type_tag() можно использовать вместе с исходной типовой меткой, чтобы определить, был ли объект JavaScript ранее «помечен» этой меткой. Это обеспечивает проверку типов с более высокой точностью, чем может обеспечить napi_instanceof(), поскольку такие типовые метки сохраняются при изменении прототипа, а также при выгрузке и повторной загрузке аддона.
Продолжая приведённый выше пример, следующая заготовка реализации аддона демонстрирует использование napi_type_tag_object() и napi_check_object_type_tag().
// This value is the type tag for a database handle. The command
//
// uuidgen | sed -r -e 's/-//g' -e 's/(.{16})(.*)/0x\1, 0x\2/'
//
// can be used to obtain the two values with which to initialize the structure.
static const napi_type_tag DatabaseHandleTypeTag = {
0x1edf75a38336451d, 0xa5ed9ce2e4c00c38
};
// This value is the type tag for a query handle.
static const napi_type_tag QueryHandleTypeTag = {
0x9c73317f9fad44a3, 0x93c3920bf3b0ad6a
};
static napi_value
openDatabase(napi_env env, napi_callback_info info) {
napi_status status;
napi_value result;
// Perform the underlying action which results in a database handle.
DatabaseHandle* dbHandle = open_database();
// Create a new, empty JS object.
status = napi_create_object(env, &result);
if (status != napi_ok) return NULL;
// Tag the object to indicate that it holds a pointer to a `DatabaseHandle`.
status = napi_type_tag_object(env, result, &DatabaseHandleTypeTag);
if (status != napi_ok) return NULL;
// Store the pointer to the `DatabaseHandle` structure inside the JS object.
status = napi_wrap(env, result, dbHandle, NULL, NULL, NULL);
if (status != napi_ok) return NULL;
return result;
}
// Later when we receive a JavaScript object purporting to be a database handle
// we can use `napi_check_object_type_tag()` to ensure that it is indeed such a
// handle.
static napi_value
query(napi_env env, napi_callback_info info) {
napi_status status;
size_t argc = 2;
napi_value argv[2];
bool is_db_handle;
status = napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
if (status != napi_ok) return NULL;
// Check that the object passed as the first parameter has the previously
// applied tag.
status = napi_check_object_type_tag(env,
argv[0],
&DatabaseHandleTypeTag,
&is_db_handle);
if (status != napi_ok) return NULL;
// Throw a `TypeError` if it doesn't.
if (!is_db_handle) {
// Throw a TypeError.
return NULL;
}
} copy
napi_define_class
napi_status napi_define_class(napi_env env,
const char* utf8name,
size_t length,
napi_callback constructor,
void* data,
size_t property_count,
const napi_property_descriptor* properties,
napi_value* result); copy -
[in] env: окружение, в котором вызывается API. -
[in] utf8name: имя функции-конструктора JavaScript. Для ясности при обёртывании класса C++ рекомендуется использовать имя класса C++. -
[in] length: длинаutf8nameв байтах илиNAPI_AUTO_LENGTH, если строка завершается нулевым символом. -
[in] constructor: функция обратного вызова, обрабатывающая создание экземпляров класса. При обёртывании класса C++ этот метод должен быть статическим членом с сигнатуройnapi_callback. Использовать конструктор класса C++ нельзя. Дополнительные сведения приведены в разделеnapi_callback. -
[in] data: дополнительные данные, передаваемые функции обратного вызова конструктора в качестве свойстваdataобъекта с информацией о вызове. -
[in] property_count: количество элементов в аргументе-массивеproperties. -
[in] properties: массив дескрипторов свойств, описывающих свойства данных, методы доступа и методы класса — статические и экземпляра. См.napi_property_descriptor. -
[out] result:napi_value, представляющий функцию-конструктор класса.
Возвращает napi_ok, если API выполнен успешно.
Определяет класс JavaScript, включая:
- Функцию-конструктор JavaScript с именем класса. При обёртывании соответствующего класса C++ функция обратного вызова, переданная через
constructor, может использоваться для создания нового экземпляра класса C++, который затем можно поместить внутрь создаваемого экземпляра объекта JavaScript с помощьюnapi_wrap. - Свойства функции-конструктора, реализация которых может вызывать соответствующие статические свойства данных, методы доступа и методы класса C++ (определённые дескрипторами свойств с атрибутом
napi_static). - Свойства объекта
prototypeфункции-конструктора. При обёртывании класса C++ нестатические свойства данных, методы доступа и методы класса C++ можно вызывать из статических функций, указанных в дескрипторах свойств без атрибутаnapi_static, предварительно получив экземпляр класса C++, помещённый внутрь экземпляра объекта JavaScript с помощьюnapi_unwrap.
При обёртывании класса C++ функция обратного вызова конструктора C++, переданная через constructor, должна быть статическим методом класса, который вызывает фактический конструктор класса, затем оборачивает новый экземпляр C++ в объект JavaScript и возвращает объект-обёртку. Подробности см. в разделе napi_wrap.
Функцию-конструктор JavaScript, возвращённую из napi_define_class, часто сохраняют для последующего создания экземпляров класса из собственного кода и/или проверки того, являются ли переданные значения экземплярами класса. В этом случае, чтобы значение функции не было удалено сборщиком мусора, для неё можно создать сильную постоянную ссылку с помощью napi_create_reference, гарантируя, что счётчик ссылок останется >= 1.
Любые данные, не являющиеся NULL и переданные этому API через параметр data или поле data элементов массива napi_property_descriptor, можно связать с полученным конструктором JavaScript (который возвращается в параметре result) и освободить при сборке мусора для класса, передав функцию JavaScript и данные в napi_add_finalizer.
napi_wrap
napi_status napi_wrap(napi_env env,
napi_value js_object,
void* native_object,
napi_finalize finalize_cb,
void* finalize_hint,
napi_ref* result); copy -
[in] env: окружение, в котором вызывается API. -
[in] js_object: объект JavaScript, который будет обёрткой для собственного объекта. -
[in] native_object: собственный экземпляр, который будет обёрнут в объект JavaScript. -
[in] finalize_cb: необязательная собственная функция обратного вызова, которая может освободить собственный экземпляр после сборки мусора для объекта JavaScript. Дополнительные сведения приведены в разделеnapi_finalize. -
[in] finalize_hint: необязательная контекстная подсказка, передаваемая функции обратного вызова финализации. -
[out] result: необязательная ссылка на обёрнутый объект.
Возвращает napi_ok, если API выполнен успешно.
Оборачивает собственный экземпляр в объект JavaScript. Позднее собственный экземпляр можно получить с помощью napi_unwrap().
Когда код JavaScript вызывает конструктор класса, определённого с помощью napi_define_class(), вызывается napi_callback конструктора. После создания экземпляра собственного класса функция обратного вызова должна вызвать napi_wrap(), чтобы обернуть только что созданный экземпляр в уже созданный объект JavaScript, являющийся аргументом this функции обратного вызова конструктора. (Этот объект this был создан на основе prototype функции-конструктора, поэтому определения всех свойств и методов экземпляра уже имеются в нём.)
Обычно при обёртывании экземпляра класса следует предоставить функцию обратного вызова финализации, которая просто удаляет собственный экземпляр, полученный в качестве аргумента data функции обратного вызова финализации.
Необязательная возвращаемая ссылка изначально является слабой, то есть её счётчик ссылок равен 0. Обычно этот счётчик ссылок временно увеличивают во время асинхронных операций, требующих, чтобы экземпляр оставался действительным.
Предупреждение: необязательную возвращаемую ссылку (если она получена) следует удалять с помощью napi_delete_reference ТОЛЬКО в ответ на вызов функции обратного вызова финализации. Если удалить её раньше, функция обратного вызова финализации может так и не быть вызвана. Поэтому при получении ссылки также требуется функция обратного вызова финализации, обеспечивающая корректное освобождение ссылки.
Вызовы функций обратного вызова финализации могут откладываться, в результате чего возникает промежуток времени, когда объект уже собран сборщиком мусора (и слабая ссылка недействительна), но финализатор ещё не вызван. При использовании napi_get_reference_value() для слабых ссылок, возвращённых napi_wrap(), необходимо также обрабатывать пустой результат.
Повторный вызов napi_wrap() для того же объекта приведёт к ошибке. Чтобы связать с объектом другой собственный экземпляр, сначала используйте napi_remove_wrap().
napi_unwrap
napi_status napi_unwrap(napi_env env,
napi_value js_object,
void** result); copy -
[in] env: окружение, в котором вызывается API. -
[in] js_object: объект, связанный с собственным экземпляром. -
[out] result: указатель на обёрнутый собственный экземпляр.
Возвращает napi_ok, если API выполнен успешно.
Получает собственный экземпляр, ранее обёрнутый в объект JavaScript с помощью napi_wrap().
Когда код JavaScript вызывает метод или метод доступа к свойству класса, вызывается соответствующая функция napi_callback. Если функция обратного вызова относится к методу или методу доступа экземпляра, аргумент this этой функции — объект-обёртка; обёрнутый экземпляр C++, являющийся объектом вызова, можно получить, вызвав napi_unwrap() для объекта-обёртки.
napi_remove_wrap
napi_status napi_remove_wrap(napi_env env,
napi_value js_object,
void** result); copy -
[in] env: окружение, в котором вызывается API. -
[in] js_object: объект, связанный с собственным экземпляром. -
[out] result: указатель на обёрнутый собственный экземпляр.
Возвращает napi_ok, если API выполнен успешно.
Получает собственный экземпляр, ранее обёрнутый в объект JavaScript js_object с помощью napi_wrap(), и снимает обёртку. Если с обёрткой была связана функция обратного вызова финализации, она больше не будет вызвана после сборки мусора для объекта JavaScript.
napi_type_tag_object
napi_status napi_type_tag_object(napi_env env,
napi_value js_object,
const napi_type_tag* type_tag); copy -
[in] env: окружение, в котором вызывается API. -
[in] js_object: объект JavaScript или внешний объект, который нужно пометить. -
[in] type_tag: метка, которой нужно пометить объект.
Возвращает napi_ok, если API выполнен успешно.
Связывает значение указателя type_tag с объектом JavaScript или внешним объектом. Затем napi_check_object_type_tag() можно использовать для сравнения метки, прикреплённой к объекту, с меткой, принадлежащей аддону, чтобы убедиться, что объект имеет правильный тип.
Если с объектом уже связана типовая метка, этот API вернёт napi_invalid_arg.
napi_check_object_type_tag
napi_status napi_check_object_type_tag(napi_env env,
napi_value js_object,
const napi_type_tag* type_tag,
bool* result); copy -
[in] env: окружение, в котором вызывается API. -
[in] js_object: объект JavaScript или внешний объект, типовую метку которого нужно проверить. -
[in] type_tag: метка, с которой нужно сравнить любую метку, найденную у объекта. -
[out] result: совпадает ли указанная типовая метка с типовой меткой объекта.falseтакже возвращается, если у объекта не найдена типовая метка.
Возвращает napi_ok, если API выполнен успешно.
Сравнивает указанный указатель type_tag с любой меткой, найденной у js_object. Если метка не найдена у js_object или найдена, но не совпадает с type_tag, то result устанавливается в значение false. Если метка найдена и совпадает с type_tag, то result устанавливается в значение true.
napi_add_finalizer
napi_status napi_add_finalizer(napi_env env,
napi_value js_object,
void* finalize_data,
node_api_basic_finalize finalize_cb,
void* finalize_hint,
napi_ref* result); copy -
[in] env: окружение, в котором вызывается API. -
[in] js_object: объект JavaScript, к которому будут присоединены собственные данные. -
[in] finalize_data: необязательные данные, передаваемые вfinalize_cb. -
[in] finalize_cb: собственная функция обратного вызова, которая будет использоваться для освобождения собственных данных после сборки мусора для объекта JavaScript. Дополнительные сведения приведены в разделеnapi_finalize. -
[in] finalize_hint: необязательная контекстная подсказка, передаваемая функции обратного вызова финализации. -
[out] result: необязательная ссылка на объект JavaScript.
Возвращает napi_ok, если API выполнен успешно.
Добавляет функцию обратного вызова napi_finalize, которая будет вызвана после сборки мусора для объекта JavaScript в js_object.
Этот API можно вызывать несколько раз для одного объекта JavaScript.
Предупреждение: необязательную возвращаемую ссылку (если она получена) следует удалять с помощью napi_delete_reference ТОЛЬКО в ответ на вызов функции обратного вызова финализации. Если удалить её раньше, функция обратного вызова финализации может так и не быть вызвана. Поэтому при получении ссылки также требуется функция обратного вызова финализации, обеспечивающая корректное освобождение ссылки.
node_api_post_finalizer
napi_status node_api_post_finalizer(node_api_basic_env env,
napi_finalize finalize_cb,
void* finalize_data,
void* finalize_hint); copy -
[in] env: окружение, в котором вызывается API. -
[in] finalize_cb: собственная функция обратного вызова, которая будет использоваться для освобождения собственных данных после сборки мусора для объекта JavaScript. Дополнительные сведения приведены в разделеnapi_finalize. -
[in] finalize_data: необязательные данные, передаваемые вfinalize_cb. -
[in] finalize_hint: необязательная контекстная подсказка, передаваемая функции обратного вызова финализации.
Возвращает napi_ok, если API выполнен успешно.
Планирует асинхронный вызов функции обратного вызова napi_finalize в цикле событий.
Обычно финализаторы вызываются во время сборки объектов сборщиком мусора (GC). В этот момент вызов любого Node-API, который может изменить состояние сборщика мусора, будет запрещён и приведёт к аварийному завершению Node.js.
node_api_post_finalizer помогает обойти это ограничение, позволяя аддону откладывать вызовы таких Node-API до момента после завершения финализации сборщиком мусора.
Простые асинхронные операции
Модулям-аддонам часто требуется использовать асинхронные вспомогательные средства из libuv в своей реализации. Это позволяет планировать выполнение задач в асинхронном режиме, чтобы методы могли возвращать управление до завершения работы. Благодаря этому они не блокируют выполнение приложения Node.js в целом.
Node-API предоставляет ABI-стабильный интерфейс для этих вспомогательных функций, охватывающий наиболее распространённые сценарии асинхронной работы.
Node-API определяет структуру napi_async_work, используемую для управления асинхронными рабочими задачами. Экземпляры создаются и удаляются с помощью napi_create_async_work и napi_delete_async_work.
Функции обратного вызова execute и complete вызываются соответственно, когда исполнитель готов начать работу и когда он завершает задачу.
Функция execute должна избегать вызовов Node-API, которые могут привести к выполнению JavaScript или взаимодействию с объектами JavaScript. Чаще всего любой код, которому необходимо вызывать Node-API, следует размещать в функции обратного вызова complete. Избегайте использования параметра napi_env в функции обратного вызова выполнения, поскольку это, скорее всего, приведёт к выполнению JavaScript.
Эти функции реализуют следующие интерфейсы:
typedef void (*napi_async_execute_callback)(napi_env env,
void* data);
typedef void (*napi_async_complete_callback)(napi_env env,
napi_status status,
void* data); copy При вызове этих методов передаваемый параметр data будет содержать данные void*, предоставленные аддоном и переданные в вызов napi_create_async_work.
После создания асинхронную рабочую задачу можно поставить в очередь на выполнение с помощью функции napi_queue_async_work:
napi_status napi_queue_async_work(node_api_basic_env env,
napi_async_work work); copy Функцию napi_cancel_async_work можно использовать, если работу требуется отменить до её начала.
После вызова napi_cancel_async_work функция обратного вызова complete будет вызвана со значением состояния napi_cancelled. Работу нельзя удалять до вызова функции обратного вызова complete, даже если она была отменена.
napi_create_async_work
napi_status napi_create_async_work(napi_env env,
napi_value async_resource,
napi_value async_resource_name,
napi_async_execute_callback execute,
napi_async_complete_callback complete,
void* data,
napi_async_work* result); copy -
[in] env: окружение, в котором вызывается API. -
[in] async_resource: необязательный объект, связанный с асинхронной работой, который будет передан возможным хукамasync_hooksinit. -
[in] async_resource_name: идентификатор типа ресурса, предоставляемый для диагностической информации, доступной через APIasync_hooks. -
[in] execute: собственная функция, которая должна асинхронно выполнять логику. Указанная функция вызывается в потоке из пула рабочих потоков и может выполняться параллельно с потоком основного цикла событий. -
[in] complete: собственная функция, которая будет вызвана после завершения асинхронной логики или её отмены. Указанная функция вызывается в потоке основного цикла событий. Дополнительные сведения приведены в разделеnapi_async_complete_callback. -
[in] data: предоставленный пользователем контекст данных. Он будет передан обратно функциям выполнения и завершения. -
[out] result:napi_async_work*— дескриптор только что созданной асинхронной рабочей задачи.
Возвращает napi_ok, если API выполнен успешно.
Этот API выделяет объект рабочей задачи, используемый для асинхронного выполнения логики. Когда задача больше не нужна, объект следует освободить с помощью napi_delete_async_work.
async_resource_name должна быть строкой в кодировке UTF-8 с завершающим нулевым символом.
Идентификатор async_resource_name предоставляется пользователем и должен отражать тип выполняемой асинхронной работы. Также рекомендуется задавать для идентификатора пространство имён, например включать в него имя модуля. Дополнительные сведения см. в документации async_hooks.
napi_delete_async_work
napi_status napi_delete_async_work(napi_env env,
napi_async_work work); copy -
[in] env: окружение, в котором вызывается API. -
[in] work: дескриптор, возвращённый вызовомnapi_create_async_work.
Возвращает napi_ok, если API выполнен успешно.
Этот API освобождает ранее выделенный объект рабочей задачи.
Этот API можно вызывать, даже если имеется ожидающее исключение JavaScript.
napi_queue_async_work
napi_status napi_queue_async_work(node_api_basic_env env,
napi_async_work work); copy -
[in] env: окружение, в котором вызывается API. -
[in] work: дескриптор, возвращённый вызовомnapi_create_async_work.
Возвращает napi_ok, если API выполнен успешно.
Этот API запрашивает выполнение ранее выделенной рабочей задачи. После успешного возврата его нельзя повторно вызывать с тем же элементом napi_async_work, иначе результат будет неопределённым.
napi_cancel_async_work
napi_status napi_cancel_async_work(node_api_basic_env env,
napi_async_work work); copy -
[in] env: окружение, в котором вызывается API. -
[in] work: дескриптор, возвращённый вызовомnapi_create_async_work.
Возвращает napi_ok, если API выполнен успешно.
Этот API отменяет поставленную в очередь работу, если она ещё не началась. Если выполнение уже началось, отменить работу нельзя, и будет возвращено значение napi_generic_failure. В случае успеха функция обратного вызова complete будет вызвана со значением состояния napi_cancelled. Работу нельзя удалять до вызова функции обратного вызова complete, даже если её удалось успешно отменить.
Этот API можно вызывать, даже если имеется ожидающее исключение JavaScript.
Пользовательские асинхронные операции
Приведённые выше простые API для асинхронной работы могут подходить не для всех сценариев. При использовании любого другого асинхронного механизма необходимы следующие API, чтобы среда выполнения могла корректно отслеживать асинхронную операцию.
napi_async_init
napi_status napi_async_init(napi_env env,
napi_value async_resource,
napi_value async_resource_name,
napi_async_context* result) copy -
[in] env: Среда, в которой вызывается API. -
[in] async_resource: Объект, связанный с асинхронной работой, который будет передан возможным хукамinitasync_hooksи доступен черезasync_hooks.executionAsyncResource(). -
[in] async_resource_name: Идентификатор типа ресурса, предоставляемого для диагностической информации, доступной через APIasync_hooks. -
[out] result: Инициализированный асинхронный контекст.
Возвращает napi_ok, если API выполнен успешно.
Объект async_resource необходимо сохранять, пока не будет вызван napi_async_destroy, чтобы API, связанные с async_hooks, работали корректно. Для сохранения совместимости ABI с предыдущими версиями объекты napi_async_context не поддерживают сильную ссылку на объекты async_resource, чтобы не допустить утечек памяти. Однако, если объект async_resource будет собран сборщиком мусора JavaScript до того, как napi_async_context будет уничтожен с помощью napi_async_destroy, вызов связанных с napi_async_context API, таких как napi_open_callback_scope и napi_make_callback, может привести к проблемам, например к потере асинхронного контекста при использовании API AsyncLocalStorage.
Для сохранения совместимости ABI с предыдущими версиями передача NULL для async_resource не приводит к ошибке. Однако это не рекомендуется, поскольку приведёт к нежелательному поведению хуков async_hooks init и async_hooks.executionAsyncResource(): теперь базовой реализации async_hooks необходим ресурс для обеспечения связи между асинхронными обратными вызовами.
napi_async_destroy
napi_status napi_async_destroy(napi_env env,
napi_async_context async_context); copy -
[in] env: Среда, в которой вызывается API. -
[in] async_context: Асинхронный контекст, который необходимо уничтожить.
Возвращает napi_ok, если API выполнен успешно.
Этот API можно вызывать, даже если ожидает обработки исключение JavaScript.
napi_make_callback
NAPI_EXTERN napi_status napi_make_callback(napi_env env,
napi_async_context async_context,
napi_value recv,
napi_value func,
size_t argc,
const napi_value* argv,
napi_value* result); copy -
[in] env: Среда, в которой вызывается API. -
[in] async_context: Контекст асинхронной операции, в которой вызывается обратный вызов. Обычно это значение, ранее полученное с помощьюnapi_async_init. Для сохранения совместимости ABI с предыдущими версиями передачаNULLдляasync_contextне приводит к ошибке. Однако это приводит к некорректной работе асинхронных хуков. Возможные проблемы включают потерю асинхронного контекста при использовании APIAsyncLocalStorage. -
[in] recv: Значениеthis, передаваемое вызываемой функции. -
[in] func:napi_value, представляющий вызываемую функцию JavaScript. -
[in] argc: Количество элементов в массивеargv. -
[in] argv: Массив значений JavaScript в видеnapi_value, представляющих аргументы функции. Еслиargcравно нулю, этот параметр можно опустить, передавNULL. -
[out] result:napi_value, представляющий возвращённый объект JavaScript.
Возвращает napi_ok, если API выполнен успешно.
Этот метод позволяет вызывать объект функции JavaScript из нативного дополнения. Этот API похож на napi_call_function. Однако он используется для вызова функции из нативного кода обратно в JavaScript после возврата из асинхронной операции (когда в стеке нет другого скрипта). Это довольно простая оболочка над node::MakeCallback.
Обратите внимание: использовать napi_make_callback внутри napi_async_complete_callback не требуется; в такой ситуации асинхронный контекст обратного вызова уже настроен, поэтому достаточно и правильно напрямую вызвать napi_call_function. Функция napi_make_callback может потребоваться при реализации пользовательского асинхронного поведения, в котором не используется napi_create_async_work.
Любые process.nextTick или Promise, добавленные JavaScript в очередь микрозадач во время обратного вызова, выполняются до возврата в C/C++.
napi_open_callback_scope
NAPI_EXTERN napi_status napi_open_callback_scope(napi_env env,
napi_value resource_object,
napi_async_context context,
napi_callback_scope* result) copy -
[in] env: Среда, в которой вызывается API. -
[in] resource_object: Объект, связанный с асинхронной работой, который будет передан возможным хукамasync_hooksinit. Этот параметр устарел и игнорируется во время выполнения. Вместо него используйте параметрasync_resourceвnapi_async_init. -
[in] context: Контекст асинхронной операции, в которой вызывается обратный вызов. Это значение должно быть ранее получено с помощьюnapi_async_init. -
[out] result: Только что созданная область.
В некоторых случаях (например, при разрешении промисов) необходимо, чтобы во время вызова определённых Node-API была активна область, эквивалентная области обратного вызова. Если в стеке нет другого скрипта, для открытия и закрытия необходимой области можно использовать функции napi_open_callback_scope и napi_close_callback_scope.
napi_close_callback_scope
NAPI_EXTERN napi_status napi_close_callback_scope(napi_env env,
napi_callback_scope scope) copy -
[in] env: Среда, в которой вызывается API. -
[in] scope: Область, которую необходимо закрыть.
Этот API можно вызывать, даже если ожидает обработки исключение JavaScript.
Управление версиями
napi_get_node_version
typedef struct {
uint32_t major;
uint32_t minor;
uint32_t patch;
const char* release;
} napi_node_version;
napi_status napi_get_node_version(node_api_basic_env env,
const napi_node_version** version); copy -
[in] env: Среда, в которой вызывается API. -
[out] version: Указатель на сведения о версии самого Node.js.
Возвращает napi_ok, если API выполнен успешно.
Эта функция заполняет структуру version значениями основной, дополнительной и исправительной версий запущенного Node.js, а поле release — значением process.release.name.
Возвращённый буфер выделен статически, поэтому освобождать его не требуется.
napi_get_version
napi_status napi_get_version(node_api_basic_env env,
uint32_t* result); copy -
[in] env: Среда, в которой вызывается API. -
[out] result: Наибольшая поддерживаемая версия Node-API.
Возвращает napi_ok, если API выполнен успешно.
Этот API возвращает наибольшую версию Node-API, поддерживаемую средой выполнения Node.js. Планируется, что Node-API будет расширяться: более новые выпуски Node.js могут поддерживать дополнительные функции API. Чтобы дополнение могло использовать более новую функцию при запуске в версиях Node.js, которые её поддерживают, и при этом обеспечивать резервное поведение в версиях Node.js, которые её не поддерживают:
- Вызовите
napi_get_version(), чтобы определить, доступен ли API. - Если функция доступна, динамически загрузите указатель на неё с помощью
uv_dlsym(). - Используйте динамически загруженный указатель для вызова функции.
- Если функция недоступна, предоставьте альтернативную реализацию, которая её не использует.
Управление памятью
napi_adjust_external_memory
NAPI_EXTERN napi_status napi_adjust_external_memory(node_api_basic_env env,
int64_t change_in_bytes,
int64_t* result); copy -
[in] env: Среда, в которой вызывается API. -
[in] change_in_bytes: Изменение объёма внешней памяти, сохраняемой объектами JavaScript. -
[out] result: Скорректированное значение. Оно должно отражать общий объём внешней памяти с учётом указанногоchange_in_bytes. Не следует полагаться на абсолютное значение, возвращаемое функцией. Например, реализации могут использовать один счётчик для всех дополнений или отдельный счётчик для каждого дополнения.
Возвращает napi_ok, если API выполнен успешно.
Эта функция сообщает среде выполнения примерный объём внешней памяти, сохраняемой объектами JavaScript (то есть объект JavaScript ссылается на собственную память, выделенную нативным дополнением). Регистрация внешней памяти может приводить к более частому запуску глобальной сборки мусора, но это не гарантируется.
Эту функцию необходимо вызывать так, чтобы дополнение не уменьшало объём внешней памяти сильнее, чем оно его увеличило.
Промисы
Node-API предоставляет средства для создания объектов Promise, описанных в разделе «Объекты Promise» спецификации ECMA. Промисы реализованы в виде пары объектов. При создании промиса с помощью napi_create_promise() создаётся и возвращается объект «отложенного выполнения» (deferred) вместе с Promise. Объект deferred связан с созданным Promise и является единственным способом разрешить или отклонить Promise с помощью napi_resolve_deferred() или napi_reject_deferred(). Объект deferred, созданный с помощью napi_create_promise(), освобождается функцией napi_resolve_deferred() или napi_reject_deferred(). Объект Promise можно вернуть в JavaScript, где его можно использовать обычным образом.
Например, чтобы создать промис и передать его асинхронному обработчику:
napi_deferred deferred; napi_value promise; napi_status status; // Create the promise. status = napi_create_promise(env, &deferred, &promise); if (status != napi_ok) return NULL; // Pass the deferred to a function that performs an asynchronous action. do_something_asynchronous(deferred); // Return the promise to JS return promise; copy
Приведённая выше функция do_something_asynchronous() выполнит асинхронное действие, а затем разрешит или отклонит объект deferred, завершив тем самым промис и освободив объект deferred:
napi_deferred deferred;
napi_value undefined;
napi_status status;
// Create a value with which to conclude the deferred.
status = napi_get_undefined(env, &undefined);
if (status != napi_ok) return NULL;
// Resolve or reject the promise associated with the deferred depending on
// whether the asynchronous action succeeded.
if (asynchronous_action_succeeded) {
status = napi_resolve_deferred(env, deferred, undefined);
} else {
status = napi_reject_deferred(env, deferred, undefined);
}
if (status != napi_ok) return NULL;
// At this point the deferred has been freed, so we should assign NULL to it.
deferred = NULL; copy
napi_create_promise
napi_status napi_create_promise(napi_env env,
napi_deferred* deferred,
napi_value* promise); copy -
[in] env: Среда, в которой вызывается API. -
[out] deferred: Вновь созданный объект deferred, который позднее можно передать вnapi_resolve_deferred()илиnapi_reject_deferred(), чтобы соответственно разрешить или отклонить связанный с ним промис. -
[out] promise: Промис JavaScript, связанный с объектом deferred.
Возвращает napi_ok, если API выполнен успешно.
Этот API создаёт объект deferred и промис JavaScript.
napi_resolve_deferred
napi_status napi_resolve_deferred(napi_env env,
napi_deferred deferred,
napi_value resolution); copy -
[in] env: Среда, в которой вызывается API. -
[in] deferred: Объект deferred, связанный промис которого необходимо разрешить. -
[in] resolution: Значение, которым необходимо разрешить промис.
Этот API разрешает промис JavaScript с помощью связанного с ним объекта deferred. Поэтому его можно использовать только для разрешения промисов JavaScript, для которых доступен соответствующий объект deferred. Это означает, что промис должен быть создан с помощью napi_create_promise(), а возвращённый этим вызовом объект deferred необходимо сохранить, чтобы передать его этому API.
После успешного выполнения объект deferred освобождается.
napi_reject_deferred
napi_status napi_reject_deferred(napi_env env,
napi_deferred deferred,
napi_value rejection); copy -
[in] env: Среда, в которой вызывается API. -
[in] deferred: Объект deferred, связанный промис которого необходимо разрешить. -
[in] rejection: Значение, которым необходимо отклонить промис.
Этот API отклоняет промис JavaScript с помощью связанного с ним объекта deferred. Поэтому его можно использовать только для отклонения промисов JavaScript, для которых доступен соответствующий объект deferred. Это означает, что промис должен быть создан с помощью napi_create_promise(), а возвращённый этим вызовом объект deferred необходимо сохранить, чтобы передать его этому API.
После успешного выполнения объект deferred освобождается.
napi_is_promise
napi_status napi_is_promise(napi_env env,
napi_value value,
bool* is_promise); copy -
[in] env: Среда, в которой вызывается API. -
[in] value: Проверяемое значение -
[out] is_promise: Флаг, указывающий, является лиpromiseнативным объектом Promise (то есть объектом Promise, созданным базовым движком).
Выполнение скриптов
Node-API предоставляет API для выполнения строки с кодом JavaScript с помощью базового движка JavaScript.
napi_run_script
NAPI_EXTERN napi_status napi_run_script(napi_env env,
napi_value script,
napi_value* result); copy -
[in] env: Среда, в которой вызывается API. -
[in] script: Строка JavaScript со скриптом для выполнения. -
[out] result: Значение, полученное в результате выполнения скрипта.
Эта функция выполняет строку кода JavaScript и возвращает результат с учётом следующих особенностей:
- В отличие от
eval, эта функция не позволяет скрипту обращаться к текущей лексической области видимости, а значит, и к области видимости модуля; поэтому псевдоглобальные переменные, напримерrequire, будут недоступны. - Скрипт может обращаться к глобальной области видимости. Объявления функций и
varв скрипте будут добавлены в объектglobal. Объявленные с помощьюletиconstпеременные будут доступны глобально, но не будут добавлены в объектglobal. - Внутри скрипта значением
thisявляетсяglobal.
Цикл событий libuv
Node-API предоставляет функцию для получения текущего цикла событий, связанного с определённым napi_env.
napi_get_uv_event_loop
NAPI_EXTERN napi_status napi_get_uv_event_loop(node_api_basic_env env,
struct uv_loop_s** loop); copy -
[in] env: Среда, в которой вызывается API. -
[out] loop: Текущий экземпляр цикла libuv.
Примечание. Хотя libuv оставалась относительно стабильной с течением времени, она не гарантирует стабильность ABI. Следует избегать использования этой функции. Её использование может привести к тому, что дополнение не будет работать в разных версиях Node.js. Для многих сценариев можно использовать асинхронные потокобезопасные вызовы функций.
Асинхронные потокобезопасные вызовы функций
Функции JavaScript обычно можно вызывать только из основного потока нативного аддона. Если аддон создаёт дополнительные потоки, функции Node-API, которым требуется napi_env, napi_value или napi_ref, нельзя вызывать из этих потоков.
Если у аддона есть дополнительные потоки и функции JavaScript требуется вызывать по завершении обработки в этих потоках, они должны взаимодействовать с основным потоком аддона, чтобы основной поток мог от их имени вызвать функцию JavaScript. API потокобезопасных функций позволяют легко это сделать.
Эти API предоставляют тип napi_threadsafe_function, а также API для создания, уничтожения и вызова объектов этого типа. napi_create_threadsafe_function() создаёт постоянную ссылку на napi_value, содержащий функцию JavaScript, которую можно вызывать из нескольких потоков. Вызовы выполняются асинхронно. Это означает, что значения, с которыми нужно вызвать колбэк JavaScript, помещаются в очередь, и для каждого значения в очереди в конечном итоге будет выполнен вызов функции JavaScript.
При создании napi_threadsafe_function можно указать колбэк napi_finalize. Этот колбэк будет вызван в основном потоке непосредственно перед уничтожением потокобезопасной функции. Он получает контекст и данные для финализации, переданные при создании, и позволяет выполнить очистку после завершения работы потоков, например вызвав uv_thread_join(). После завершения колбэка финализации никакие потоки, кроме потока основного цикла, не должны использовать потокобезопасную функцию.
Значение context, переданное при вызове napi_create_threadsafe_function(), можно получить из любого потока вызовом napi_get_threadsafe_function_context().
Вызов потокобезопасной функции
napi_call_threadsafe_function() можно использовать для вызова JavaScript. napi_call_threadsafe_function() принимает параметр, определяющий, будет ли API работать в блокирующем режиме. Если задано napi_tsfn_nonblocking, API работает в неблокирующем режиме и возвращает napi_queue_full, если очередь заполнена, препятствуя успешному добавлению данных в очередь. Если задано napi_tsfn_blocking, API блокируется до появления свободного места в очереди. napi_call_threadsafe_function() никогда не блокируется, если потокобезопасная функция создана с максимальным размером очереди 0.
napi_call_threadsafe_function() не следует вызывать с napi_tsfn_blocking из потока JavaScript, поскольку при заполненной очереди это может привести к взаимной блокировке потока JavaScript.
Фактический вызов JavaScript определяется колбэком, переданным через параметр call_js_cb. call_js_cb вызывается в основном потоке для каждого значения, помещённого в очередь успешным вызовом napi_call_threadsafe_function(). Если такой колбэк не задан, будет использован колбэк по умолчанию, и вызов JavaScript будет выполнен без аргументов. Колбэк call_js_cb получает вызываемую функцию JavaScript в качестве napi_value среди параметров, а также указатель на контекст void*, использованный при создании napi_threadsafe_function, и следующий указатель на данные, созданный одним из вторичных потоков. Затем колбэк может использовать такой API, как napi_call_function(), для вызова JavaScript.
Колбэк также может быть вызван с env и call_js_cb, равными NULL, чтобы указать, что вызовы JavaScript больше невозможны, хотя в очереди остаются элементы, которые, возможно, потребуется освободить. Обычно это происходит, когда процесс Node.js завершается, пока потокобезопасная функция ещё активна.
Вызывать JavaScript через napi_make_callback() не требуется, поскольку Node-API запускает call_js_cb в контексте, подходящем для колбэков.
За один такт цикла событий может быть вызвано ноль или более элементов очереди. Приложениям не следует полагаться на какое-либо конкретное поведение, кроме того, что вызовы колбэков будут продвигаться вперёд, а события будут вызываться с течением времени.
Подсчёт ссылок на потокобезопасные функции
Потоки можно добавлять к объекту napi_threadsafe_function и удалять из него в течение всего срока его существования. Поэтому, помимо указания начального количества потоков при создании, можно вызвать napi_acquire_threadsafe_function, чтобы указать, что новый поток начнёт использовать потокобезопасную функцию. Аналогично, можно вызвать napi_release_threadsafe_function, чтобы указать, что существующий поток прекратит использовать потокобезопасную функцию.
Объекты napi_threadsafe_function уничтожаются, когда каждый использующий объект поток вызвал napi_release_threadsafe_function() или получил статус возврата napi_closing в ответ на вызов napi_call_threadsafe_function. Очередь очищается до уничтожения napi_threadsafe_function. napi_release_threadsafe_function() должен быть последним вызовом API, связанным с данным napi_threadsafe_function, поскольку после завершения вызова нет гарантии, что napi_threadsafe_function всё ещё выделен. По той же причине не используйте потокобезопасную функцию после получения значения возврата napi_closing в ответ на вызов napi_call_threadsafe_function. Данные, связанные с napi_threadsafe_function, можно освободить в колбэке napi_finalize, переданном в napi_create_threadsafe_function(). Параметр initial_thread_count функции napi_create_threadsafe_function задаёт начальное количество получений потокобезопасной функции, избавляя от необходимости многократно вызывать napi_acquire_threadsafe_function при создании.
Когда количество потоков, использующих napi_threadsafe_function, достигает нуля, никакие новые потоки не могут начать его использовать с помощью вызова napi_acquire_threadsafe_function(). Фактически все последующие вызовы связанных с ним API, кроме napi_release_threadsafe_function(), будут возвращать ошибочное значение napi_closing.
Потокобезопасную функцию можно «прервать», передав значение napi_tsfn_abort в napi_release_threadsafe_function(). В результате все последующие вызовы связанных с потокобезопасной функцией API, кроме napi_release_threadsafe_function(), будут возвращать napi_closing, даже если счётчик ссылок ещё не достиг нуля. В частности, napi_call_threadsafe_function() вернёт napi_closing, сообщая потокам, что асинхронные вызовы потокобезопасной функции больше невозможны. Это можно использовать как условие завершения потока. Получив значение возврата napi_closing от napi_call_threadsafe_function(), поток больше не должен использовать потокобезопасную функцию, поскольку нет гарантии, что она всё ещё выделена.
Определение необходимости поддерживать работу процесса
Подобно дескрипторам libuv, потокобезопасные функции можно «ссылать» и «отсылать». «Сосланная» потокобезопасная функция не позволит циклу событий в потоке, в котором она создана, завершиться до уничтожения потокобезопасной функции. Напротив, «отосланная» потокобезопасная функция не препятствует завершению цикла событий. Для этой цели предназначены API napi_ref_threadsafe_function и napi_unref_threadsafe_function.
Ни napi_unref_threadsafe_function не помечает потокобезопасные функции как готовые к уничтожению, ни napi_ref_threadsafe_function не предотвращает их уничтожение.
napi_create_threadsafe_function
NAPI_EXTERN napi_status
napi_create_threadsafe_function(napi_env env,
napi_value func,
napi_value async_resource,
napi_value async_resource_name,
size_t max_queue_size,
size_t initial_thread_count,
void* thread_finalize_data,
napi_finalize thread_finalize_cb,
void* context,
napi_threadsafe_function_call_js call_js_cb,
napi_threadsafe_function* result); copy -
[in] env: Среда, в которой вызывается API. -
[in] func: Необязательная функция JavaScript для вызова из другого потока. Её необходимо указать, еслиNULLпередан вcall_js_cb. -
[in] async_resource: Необязательный объект, связанный с асинхронной работой, который будет передан возможным хукамasync_hooksinit. -
[in] async_resource_name: Строка JavaScript, задающая идентификатор типа ресурса, предоставляемого для диагностической информации, доступной через APIasync_hooks. -
[in] max_queue_size: Максимальный размер очереди.0— без ограничений. -
[in] initial_thread_count: Начальное количество получений, то есть начальное количество потоков, включая основной поток, которые будут использовать эту функцию. -
[in] thread_finalize_data: Необязательные данные, передаваемые вthread_finalize_cb. -
[in] thread_finalize_cb: Необязательная функция, вызываемая при уничтоженииnapi_threadsafe_function. -
[in] context: Необязательные данные, связываемые с созданнымnapi_threadsafe_function. -
[in] call_js_cb: Необязательный колбэк, вызывающий функцию JavaScript в ответ на вызов из другого потока. Этот колбэк будет вызван в основном потоке. Если он не задан, функция JavaScript будет вызвана без параметров, а в качестве значенияthisбудет использованоundefined. Дополнительные сведения см. в разделеnapi_threadsafe_function_call_js. -
[out] result: Асинхронная потокобезопасная функция JavaScript.
История изменений:
-
Версия 10 (
NAPI_VERSIONопределено как10или выше):Необработанные исключения, возникшие в
call_js_cb, обрабатываются событием'uncaughtException', а не игнорируются.
napi_get_threadsafe_function_context
NAPI_EXTERN napi_status
napi_get_threadsafe_function_context(napi_threadsafe_function func,
void** result); copy -
[in] func: Потокобезопасная функция, контекст которой требуется получить. -
[out] result: Место для сохранения контекста.
Этот API можно вызывать из любого потока, использующего func.
napi_call_threadsafe_function
NAPI_EXTERN napi_status
napi_call_threadsafe_function(napi_threadsafe_function func,
void* data,
napi_threadsafe_function_call_mode is_blocking); copy -
[in] func: Асинхронная потокобезопасная функция JavaScript, которую нужно вызвать. -
[in] data: Данные для передачи в JavaScript через колбэкcall_js_cb, указанный при создании потокобезопасной функции JavaScript. -
[in] is_blocking: Флаг, значением которого может бытьnapi_tsfn_blocking, чтобы указать, что вызов должен блокироваться при заполненной очереди, илиnapi_tsfn_nonblocking, чтобы указать, что вызов должен немедленно возвращать статусnapi_queue_fullпри заполненной очереди.
Этот API не следует вызывать с napi_tsfn_blocking из потока JavaScript, поскольку при заполненной очереди это может привести к взаимной блокировке потока JavaScript.
Этот API вернёт napi_closing, если napi_release_threadsafe_function() был вызван из любого потока с параметром abort, равным napi_tsfn_abort. Значение добавляется в очередь только в том случае, если API возвращает napi_ok.
Этот API можно вызывать из любого потока, использующего func.
napi_acquire_threadsafe_function
NAPI_EXTERN napi_status napi_acquire_threadsafe_function(napi_threadsafe_function func); copy
-
[in] func: Асинхронная потокобезопасная функция JavaScript, использование которой требуется начать.
Поток должен вызвать этот API до передачи func любым другим API потокобезопасных функций, чтобы указать, что он будет использовать func. Это не позволит уничтожить func после того, как все остальные потоки прекратят его использовать.
Этот API можно вызывать из любого потока, который начинает использовать func.
napi_release_threadsafe_function
NAPI_EXTERN napi_status
napi_release_threadsafe_function(napi_threadsafe_function func,
napi_threadsafe_function_release_mode mode); copy -
[in] func: Асинхронная потокобезопасная функция JavaScript, счётчик ссылок которой необходимо уменьшить. -
[in] mode: Флаг, значением которого может бытьnapi_tsfn_release, указывающий, что текущий поток больше не будет вызывать потокобезопасную функцию, илиnapi_tsfn_abort, указывающий, что никакие другие потоки, помимо текущего, также не должны больше вызывать потокобезопасную функцию. Если заданоnapi_tsfn_abort, последующие вызовыnapi_call_threadsafe_function()будут возвращатьnapi_closing, и новые значения не будут помещаться в очередь.
Поток должен вызывать этот API, когда перестаёт использовать func. Передача func любым API потокобезопасных функций после вызова этого API приводит к неопределённым результатам, поскольку func мог быть уничтожен.
Этот API можно вызывать из любого потока, который прекращает использовать func.
napi_ref_threadsafe_function
NAPI_EXTERN napi_status napi_ref_threadsafe_function(node_api_basic_env env, napi_threadsafe_function func); copy
-
[in] env: Среда, в которой вызывается API. -
[in] func: Потокобезопасная функция, на которую нужно установить ссылку.
Этот API указывает, что цикл событий, выполняющийся в основном потоке, не должен завершаться до уничтожения func. Подобно uv_ref, этот вызов идемпотентен.
Ни napi_unref_threadsafe_function не помечает потокобезопасные функции как готовые к уничтожению, ни napi_ref_threadsafe_function не предотвращает их уничтожение. Для этой цели предназначены napi_acquire_threadsafe_function и napi_release_threadsafe_function.
Этот API можно вызывать только из основного потока.
napi_unref_threadsafe_function
NAPI_EXTERN napi_status napi_unref_threadsafe_function(node_api_basic_env env, napi_threadsafe_function func); copy
-
[in] env: Среда, в которой вызывается API. -
[in] func: Потокобезопасная функция, со ссылки на которую нужно снять отметку.
Этот API указывает, что цикл событий, выполняющийся в основном потоке, может завершиться до уничтожения func. Подобно uv_unref, этот вызов идемпотентен.
Этот API можно вызывать только из основного потока.
Различные вспомогательные средства
node_api_get_module_file_name
NAPI_EXTERN napi_status node_api_get_module_file_name(node_api_basic_env env, const char** result); copy
-
[in] env: Среда, в которой вызывается API. -
[out] result: URL, содержащий абсолютный путь к расположению, из которого был загружен аддон. Для файла в локальной файловой системе он будет начинаться сfile://. Строка завершается нулевым символом, принадлежитenvи поэтому не должна изменяться или освобождаться.
result может быть пустой строкой, если в процессе загрузки аддону не удалось определить имя файла.
© Joyent, Inc. and other Node contributors
Licensed under the MIT License.
Node.js is a trademark of Joyent, Inc. and is used with its permission.
We are not endorsed by or affiliated with Joyent.
https://nodejs.org/dist/latest-v22.x/docs/api/n-api.html