Node.js v21.7.2 ドキュメント
- Node.js v21.7.2
-
► 目次
- Node-API
- ABI の安定性の意味
- ビルド
- 使い方
- Node-API バージョンマトリックス
- 環境ライフサイクル API
- 基本的な Node-API データ型
- エラー処理
- オブジェクトのライフタイム管理
- モジュール登録
- JavaScript の値の操作
- Enum 型
- オブジェクト作成関数
napi_create_array
napi_create_array_with_length
napi_create_arraybuffer
napi_create_buffer
napi_create_buffer_copy
napi_create_date
napi_create_external
napi_create_external_arraybuffer
napi_create_external_buffer
napi_create_object
napi_create_symbol
node_api_symbol_for
napi_create_typedarray
napi_create_dataview
- C 型から Node-API に変換する関数
napi_create_int32
napi_create_uint32
napi_create_int64
napi_create_double
napi_create_bigint_int64
napi_create_bigint_uint64
napi_create_bigint_words
napi_create_string_latin1
node_api_create_external_string_latin1
napi_create_string_utf16
node_api_create_external_string_utf16
napi_create_string_utf8
node_api_create_property_key_utf16
- Node-API から C 型に変換する関数
napi_get_array_length
napi_get_arraybuffer_info
napi_get_buffer_info
napi_get_prototype
napi_get_typedarray_info
napi_get_dataview_info
napi_get_date_value
napi_get_value_bool
napi_get_value_double
napi_get_value_bigint_int64
napi_get_value_bigint_uint64
napi_get_value_bigint_words
napi_get_value_external
napi_get_value_int32
napi_get_value_int64
napi_get_value_string_latin1
napi_get_value_string_utf8
napi_get_value_string_utf16
napi_get_value_uint32
- グローバルインスタンスを取得する関数
- JavaScript の値と抽象操作の操作
- JavaScript プロパティの操作
- 構造体
- 関数
napi_get_property_names
napi_get_all_property_names
napi_set_property
napi_get_property
napi_has_property
napi_delete_property
napi_has_own_property
napi_set_named_property
napi_get_named_property
napi_has_named_property
napi_set_element
napi_get_element
napi_has_element
napi_delete_element
napi_define_properties
napi_object_freeze
napi_object_seal
- JavaScript 関数の操作
- オブジェクトのラップ
- 簡単な非同期操作
- カスタム非同期操作
- バージョン管理
- メモリ管理
- プロミス
- スクリプト実行
- libuv イベントループ
- 非同期スレッドセーフ関数呼び出し
- その他のユーティリティ
- Node-API
-
► インデックス
- アサーションテスト
- 非同期コンテキスト追跡
- Async hooks
- Buffer
- C++ アドオン
- Node-API を使用した C/C++ アドオン
- C++ エンベッダー API
- 子プロセス
- Cluster
- コマンドラインオプション
- Console
- Corepack
- Crypto
- デバッガー
- 非推奨 API
- Diagnostics Channel
- DNS
- Domain
- エラー
- Events
- ファイルシステム
- グローバル
- HTTP
- HTTP/2
- HTTPS
- インスペクター
- 国際化
- モジュール: CommonJS モジュール
- モジュール: ECMAScript モジュール
- モジュール:
node:module
API - モジュール: パッケージ
- Net
- OS
- Path
- Performance hooks
- パーミッション
- Process
- Punycode
- クエリ文字列
- Readline
- REPL
- レポート
- 単一実行可能アプリケーション
- Stream
- 文字列デコーダー
- テストランナー
- タイマー
- TLS/SSL
- トレースイベント
- TTY
- UDP/データグラム
- URL
- ユーティリティ
- V8
- VM
- WASI
- Web Crypto API
- Web Streams API
- ワーカー スレッド
- Zlib
- ► 他のバージョン
- ► オプション
Node-API#
Node-API (以前の N-API) は、ネイティブアドオンを構築するための API です。基盤となる JavaScript ランタイム (例: V8) から独立しており、Node.js 自体の一部としてメンテナンスされています。この API は、Node.js のバージョン間で Application Binary Interface (ABI) の安定性を保ちます。基盤となる JavaScript エンジンの変更からアドオンを保護し、あるメジャーバージョン用にコンパイルされたモジュールが、再コンパイルなしで Node.js の後続のメジャーバージョンで実行できるようにすることを目的としています。 ABI 安定性ガイドで、より詳細な説明を提供しています。
アドオンは、C++ アドオンというタイトルのセクションで概説されているのと同じアプローチ/ツールでビルド/パッケージ化されます。唯一の違いは、ネイティブコードで使用される API のセットです。V8 や Native Abstractions for Node.js API を使用する代わりに、Node-API で利用可能な関数が使用されます。
Node-API によって公開される API は、一般に JavaScript の値を作成および操作するために使用されます。概念と操作は、一般に ECMA-262 言語仕様で指定されているアイデアに対応します。API には次のプロパティがあります。
- すべての Node-API 呼び出しは、
napi_status
型のステータスコードを返します。このステータスは、API 呼び出しが成功したか失敗したかを示します。 - API の戻り値は、出力パラメーターを介して渡されます。
- すべての JavaScript 値は、
napi_value
という名前の不透明な型で抽象化されます。 - エラーのステータスコードの場合、
napi_get_last_error_info
を使用して追加情報を取得できます。詳細については、エラー処理セクション エラー処理 を参照してください。
Node-API は、Node.js のバージョンと異なるコンパイラレベル間で ABI の安定性を確保する C API です。C++ API は使いやすくなります。C++ の使用をサポートするために、プロジェクトは node-addon-api
という C++ ラッパーモジュールを保持しています。このラッパーは、インライン化可能な C++ API を提供します。 node-addon-api
でビルドされたバイナリは、Node.js によってエクスポートされる Node-API C ベースの関数のシンボルに依存します。 node-addon-api
は、Node-API を呼び出すコードを記述するより効率的な方法です。例として、次の node-addon-api
コードを取り上げます。最初のセクションは node-addon-api
コードを示し、2 番目のセクションはアドオンで実際に使用されるものを示しています。
Object obj = Object::New(env);
obj["foo"] = String::New(env, "bar");
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;
}
最終的に、アドオンはエクスポートされたC APIのみを使用します。その結果、C APIによって提供されるABI安定性の恩恵を受けることができます。
C APIの代わりにnode-addon-api
を使用する場合は、まずnode-addon-api
のAPIドキュメントを参照してください。
Node-APIリソースは、Node-APIとnode-addon-api
を使い始めたばかりの開発者にとって、優れたオリエンテーションとヒントを提供します。追加のメディアリソースは、Node-APIメディアページにあります。
ABI安定性の影響#
Node-APIはABI安定性を保証しますが、Node.jsの他の部分は保証しておらず、アドオンから使用される外部ライブラリも保証しない場合があります。特に、以下のAPIは、メジャーバージョン間でのABI安定性を保証しません。
-
次のいずれかを介して利用可能なNode.js C++ API
#include <node.h> #include <node_buffer.h> #include <node_version.h> #include <node_object_wrap.h>
-
Node.jsに含まれており、以下を介して利用可能なlibuv API
#include <uv.h>
-
以下を介して利用可能なV8 API
#include <v8.h>
したがって、アドオンがNode.jsのメジャーバージョン間でABI互換性を維持するためには、以下の使用に限定してNode-APIのみを使用する必要があります。
#include <node_api.h>
また、使用するすべての外部ライブラリについて、外部ライブラリがNode-APIと同様のABI安定性の保証を行っていることを確認する必要があります。
ビルド#
JavaScriptで記述されたモジュールとは異なり、Node-APIを使用したNode.jsネイティブアドオンの開発とデプロイには、追加のツールセットが必要です。Node.jsの開発に必要な基本ツールに加えて、ネイティブアドオンの開発者は、CおよびC++コードをバイナリにコンパイルできるツールチェーンが必要です。さらに、ネイティブアドオンのデプロイ方法によっては、ネイティブアドオンの*ユーザー*もC/C++ツールチェーンをインストールする必要があります。
Linux開発者向けには、必要なC/C++ツールチェーンパッケージがすぐに利用できます。GCCは、さまざまなプラットフォームでビルドおよびテストするためにNode.jsコミュニティで広く使用されています。多くの開発者にとって、LLVMコンパイラインフラストラクチャも優れた選択肢です。
Mac開発者向けには、Xcodeが必要なコンパイラツールをすべて提供します。ただし、Xcode IDE全体をインストールする必要はありません。次のコマンドは、必要なツールチェーンをインストールします。
xcode-select --install
Windows開発者向けには、Visual Studioが必要なコンパイラツールをすべて提供します。ただし、Visual Studio IDE全体をインストールする必要はありません。次のコマンドは、必要なツールチェーンをインストールします。
npm install --global windows-build-tools
以下のセクションでは、Node.jsネイティブアドオンの開発とデプロイに使用できる追加のツールについて説明します。
ビルドツール#
ここにリストされている両方のツールは、ネイティブアドオンの*ユーザー*が、ネイティブアドオンを正常にインストールするためにC/C++ツールチェーンをインストールしている必要があることを前提としています。
node-gyp#
node-gypは、GoogleのGYPツールのgyp-nextフォークに基づくビルドシステムであり、npmにバンドルされています。GYP、したがってnode-gypは、Pythonがインストールされている必要があります。
歴史的に、node-gypはネイティブアドオンをビルドするためのツールとして選択されてきました。広く採用されており、ドキュメントも豊富です。ただし、一部の開発者はnode-gypに制限があることに気づいています。
CMake.js#
CMake.jsは、CMakeに基づいた代替ビルドシステムです。
CMake.jsは、すでにCMakeを使用しているプロジェクトや、node-gypの制限の影響を受けている開発者にとって、優れた選択肢です。build_with_cmake
は、CMakeベースのネイティブアドオンプロジェクトの例です。
プリコンパイル済みバイナリのアップロード#
ここにリストされている3つのツールを使用すると、ネイティブアドオンの開発者とメンテナーは、バイナリを作成して、パブリックまたはプライベートサーバーにアップロードできます。これらのツールは、通常、Travis CIやAppVeyorなどのCI/CDビルドシステムと統合されており、さまざまなプラットフォームとアーキテクチャのバイナリをビルドおよびアップロードします。これらのバイナリは、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は、CMake.jsを使用するGitHubプロジェクトに適しています。
prebuildify#
prebuildifyは、node-gypに基づいたツールです。prebuildifyの利点は、構築されたバイナリがnpmにアップロードされるときに、ネイティブアドオンにバンドルされることです。バイナリはnpmからダウンロードされ、ネイティブアドオンがインストールされると、モジュールユーザーがすぐに利用できるようになります。
使い方#
Node-API関数を使用するには、node開発ツリーのsrcディレクトリにあるnode_api.h
ファイルを含めます。
#include <node_api.h>
これにより、特定のNode.jsリリースにおけるデフォルトのNAPI_VERSION
が選択されます。特定のバージョンのNode-APIとの互換性を確保するために、ヘッダーを含める際にバージョンを明示的に指定できます。
#define NAPI_VERSION 3
#include <node_api.h>
これにより、Node-APIサーフェスが、指定された(およびそれ以前の)バージョンで利用可能だった機能のみに制限されます。
Node-APIサーフェスの一部は実験的であり、明示的なオプトインが必要です。
#define NAPI_EXPERIMENTAL
#include <node_api.h>
この場合、実験的なAPIを含むAPIサーフェス全体がモジュールコードで利用可能になります。
場合によっては、すでにリリースされて安定しているAPIに影響を与える実験的な機能が導入されることがあります。これらの機能は、オプトアウトによって無効にできます。
#define NAPI_EXPERIMENTAL
#define NODE_API_EXPERIMENTAL_<FEATURE_NAME>_OPT_OUT
#include <node_api.h>
ここで、<FEATURE_NAME>
は、実験的および安定したAPIの両方に影響を与える実験的な機能の名前です。
Node-APIバージョンマトリックス#
バージョン9までは、Node-APIバージョンは追加方式で、Node.jsとは独立してバージョン管理されていました。つまり、どのバージョンも以前のバージョンの拡張であり、以前のバージョンのすべてのAPIにいくつかの追加機能がありました。各Node.jsバージョンは、単一のNode-APIバージョンのみをサポートしていました。たとえば、v18.15.0はNode-APIバージョン8のみをサポートします。ABI安定性は、8が以前のすべてのバージョンの厳密なスーパーセットであったため達成されました。
バージョン9以降、Node-APIバージョンは引き続き独立してバージョン管理されますが、Node-APIバージョン9で実行されたアドオンは、Node-APIバージョン10で実行するためにコードの更新が必要になる場合があります。ただし、ABI安定性は維持されます。Node-APIバージョン8よりも高いバージョンをサポートするNode.jsバージョンは、8とサポートする最高バージョンまでのすべてのバージョンをサポートし、アドオンがより高いNode-APIバージョンを選択しない限り、デフォルトでバージョン8 APIを提供するためです。このアプローチは、ABI安定性を維持しながら、既存のNode-API関数をより最適化できる柔軟性を提供します。既存のアドオンは、以前のバージョンのNode-APIを使用して再コンパイルせずに引き続き実行できます。アドオンが新しいNode-APIバージョンからの機能を必要とする場合、既存のコードの変更と再コンパイルは、それらの新しい関数を使用するために必要になります。
Node-APIバージョン9以降をサポートするバージョンのNode.jsでは、NAPI_VERSION=X
を定義し、既存のアドオン初期化マクロを使用すると、実行時にアドオンで使用される要求されたNode-APIバージョンがアドオンに組み込まれます。NAPI_VERSION
が設定されていない場合は、デフォルトで8になります。
この表は、古いストリームでは最新ではない可能性があります。最新の情報は、Node-APIバージョンマトリックスの最新のAPIドキュメントにあります。
Node-APIバージョン | サポートされているバージョン |
---|---|
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まで進化し続けました。APIはNode.js 8.6.0より前のバージョンでは異なります。Node-APIバージョン3以降をお勧めします。
Node-API用にドキュメント化された各APIには、added in:
というヘッダーがあり、安定しているAPIには、追加のヘッダーNode-API version:
があります。APIは、Node-API version:
に示されているNode-APIバージョン以上をサポートするNode.jsバージョンを使用する場合に、直接使用できます。Node-API version:
がリストされていないか、Node-API version:
がリストされていないNode.jsバージョンを使用する場合、#define NAPI_EXPERIMENTAL
がnode_api.h
またはjs_native_api.h
のインクルードより前にある場合にのみ、APIを使用できます。APIがadded in:
に示されているよりも後のバージョンのNode.jsで利用できないように見える場合、これはおそらく見かけ上の不在の理由です。
ネイティブコードからECMAScript機能にアクセスすることに厳密に関連付けられたNode-APIは、js_native_api.h
およびjs_native_api_types.h
で個別に見つけることができます。これらのヘッダーで定義されているAPIは、node_api.h
およびnode_api_types.h
に含まれています。ヘッダーは、Node.jsの外部でNode-APIの実装を許可するために、このように構造化されています。これらの実装では、Node.js固有のAPIは適用できない場合があります。
アドオンのNode.js固有の部分は、実際の機能をJavaScript環境に公開するコードから分離して、後者をNode-APIの複数の実装で使用できるようにすることができます。以下の例では、addon.c
とaddon.h
はjs_native_api.h
のみを参照します。これにより、addon.c
がNode.jsのNode-API実装またはNode.js外部のNode-APIの実装に対してコンパイルするために再利用できることが保証されます。
addon_node.c
は、アドオンへのNode.js固有のエントリポイントを含み、アドオンがNode.js環境にロードされるときにaddon.c
を呼び出すことによってアドオンをインスタンス化する別のファイルです。
// addon.h
#ifndef _ADDON_H_
#define _ADDON_H_
#include <js_native_api.h>
napi_value create_addon(napi_env env);
#endif // _ADDON_H_
// 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;
}
// 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);
}
環境ライフサイクルAPI#
ECMAScript言語仕様のセクション8.7では、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_nogc_env env,
void* data,
napi_finalize finalize_cb,
void* finalize_hint);
[in] env
: Node-API呼び出しが実行される環境。[in] data
: このインスタンスのバインディングで利用可能にするデータ項目。[in] finalize_cb
: 環境が破棄されるときに呼び出す関数。関数は、data
を受け取り、それを解放できます。詳細については、napi_finalize
を参照してください。[in] finalize_hint
: コレクション中にfinalizeコールバックに渡すオプションのヒント。
APIが成功した場合はnapi_ok
を返します。
このAPIは、data
を現在実行中のNode.js環境に関連付けます。data
は後でnapi_get_instance_data()
を使用して取得できます。以前のnapi_set_instance_data()
の呼び出しによって設定された、現在実行中のNode.js環境に関連付けられている既存のデータはすべて上書きされます。前の呼び出しでfinalize_cb
が提供された場合、それは呼び出されません。
napi_get_instance_data
#
napi_status napi_get_instance_data(node_api_nogc_env env,
void** data);
[in] env
: Node-API呼び出しが実行される環境。[out] data
:napi_set_instance_data()
の呼び出しによって、以前に現在実行中のNode.js環境に関連付けられたデータ項目。
APIが成功した場合はnapi_ok
を返します。
このAPIは、以前にnapi_set_instance_data()
を介して現在実行中のNode.js環境に関連付けられたデータを取得します。データが設定されていない場合、呼び出しは成功し、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;
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;
error_message
: エラーのVM中立的な説明を含むUTF8エンコードされた文字列。engine_reserved
: VM固有のエラー詳細のために予約されています。これは現在、どのVMにも実装されていません。engine_error_code
: VM固有のエラーコード。これは現在、どのVMにも実装されていません。error_code
: 最後のエラーで発生したNode-APIステータスコード。
詳細については、エラー処理セクションを参照してください。
napi_env
#
napi_env
は、基盤となるNode-API実装がVM固有の状態を永続化するために使用できるコンテキストを表すために使用されます。この構造は、ネイティブ関数が呼び出されるときに渡され、Node-API呼び出しを行うときに返される必要があります。具体的には、最初のネイティブ関数が呼び出されたときに渡されたのと同じnapi_env
を、後続のネストされたNode-API呼び出しに渡す必要があります。一般的な再利用を目的としてnapi_env
をキャッシュすること、および異なるWorker
スレッドで実行されている同じアドオンのインスタンス間でnapi_env
を渡すことは許可されていません。ネイティブアドオンのインスタンスがアンロードされると、napi_env
は無効になります。このイベントの通知は、napi_add_env_cleanup_hook
およびnapi_set_instance_data
に提供されるコールバックを通じて配信されます。
node_api_nogc_env
#
このnapi_env
のバリアントは、同期ファイナライザー(node_api_nogc_finalize
)に渡されます。最初の引数としてnode_api_nogc_env
型のパラメータを受け入れるNode-APIのサブセットがあります。これらのAPIは、JavaScriptエンジンの状態にアクセスしないため、同期ファイナライザーから呼び出すのが安全です。これらのAPIにnapi_env
型のパラメータを渡すことは許可されていますが、JavaScriptエンジンの状態にアクセスするAPIにnode_api_nogc_env
型のパラメータを渡すことは許可されていません。キャストなしでそれを行おうとすると、アドオンがコンパイル時に、間違ったポインター型が関数に渡されたときに警告やエラーを発行するフラグを使用してコンパイルされた場合、コンパイラの警告またはエラーが発生します。同期ファイナライザーからそのようなAPIを呼び出すと、最終的にアプリケーションが終了します。
napi_value
#
これは、JavaScriptの値を表すために使用される不透明なポインタです。
napi_threadsafe_function
#
これは、napi_call_threadsafe_function()
を介して複数のスレッドから非同期的に呼び出すことができるJavaScript関数を表す不透明なポインタです。
napi_threadsafe_function_release_mode
#
スレッドセーフ関数をすぐに閉じる(napi_tsfn_abort
)のか、単に解放する(napi_tsfn_release
)のかを示すために、napi_release_threadsafe_function()
に与える値。これにより、後でnapi_acquire_threadsafe_function()
およびnapi_call_threadsafe_function()
を介して使用できるようになります。
typedef enum {
napi_tsfn_release,
napi_tsfn_abort
} napi_threadsafe_function_release_mode;
napi_threadsafe_function_call_mode
#
スレッドセーフ関数に関連付けられたキューがいっぱいの場合に、呼び出しをブロックする必要があるかどうかを示すために、napi_call_threadsafe_function()
に与える値。
typedef enum {
napi_tsfn_nonblocking,
napi_tsfn_blocking
} napi_threadsafe_function_call_mode;
Node-APIメモリ管理型#
napi_handle_scope
#
これは、特定のスコープ内で作成されたオブジェクトの寿命を制御および変更するために使用される抽象化です。一般に、Node-APIの値はハンドルスコープのコンテキスト内で作成されます。JavaScriptからネイティブメソッドが呼び出されると、デフォルトのハンドルスコープが存在します。ユーザーが明示的に新しいハンドルスコープを作成しない場合、Node-APIの値はデフォルトのハンドルスコープで作成されます。ネイティブメソッドの実行外のコードの呼び出し(たとえば、libuvコールバックの呼び出し中)の場合、モジュールはJavaScript値の作成につながる可能性のある関数を呼び出す前に、スコープを作成する必要があります。
ハンドルスコープは、napi_open_handle_scope
を使用して作成され、napi_close_handle_scope
を使用して破棄されます。スコープを閉じると、ハンドルスコープの有効期間中に作成されたすべてのnapi_value
が現在のスタックフレームから参照されなくなったことをGCに示すことができます。
詳細については、オブジェクトの寿命管理を確認してください。
napi_escapable_handle_scope
#
エスケープ可能なハンドルスコープは、特定のハンドルスコープ内で作成された値を親スコープに返すための特別なタイプのハンドルスコープです。
napi_ref
#
これは、napi_value
を参照するために使用する抽象化です。これにより、ユーザーはJavaScriptの値の寿命を管理でき、最小寿命を明示的に定義することもできます。
詳細については、オブジェクトの寿命管理を確認してください。
napi_type_tag
#
2つの符号なし64ビット整数として格納された128ビットの値。これは、JavaScriptオブジェクトまたはexternalsが特定の型であることを保証するために「タグ付け」できるUUIDとして機能します。これは、オブジェクトのプロトタイプが操作された場合に誤検知を報告する可能性がある後者のnapi_instanceof
よりも強力なチェックです。型タグ付けは、以前にJavaScriptオブジェクトに適用された型タグに対応するネイティブ型に、ラップされたオブジェクトから取得したポインタを安全にキャストできることを保証するため、napi_wrap
と組み合わせて使用するのが最も役立ちます。
typedef struct {
uint64_t lower;
uint64_t upper;
} napi_type_tag;
napi_async_cleanup_hook_handle
#
napi_add_async_cleanup_hook
によって返される不透明な値。非同期クリーンアップイベントのチェーンが完了したときに、napi_remove_async_cleanup_hook
に渡す必要があります。
Node-APIコールバック型#
napi_callback_info
#
コールバック関数に渡される不透明なデータ型。コールバックが呼び出されたコンテキストに関する追加情報を取得するために使用できます。
napi_callback
#
Node-APIを介してJavaScriptに公開されるユーザー提供のネイティブ関数の関数ポインタ型。コールバック関数は、次のシグネチャを満たす必要があります。
typedef napi_value (*napi_callback)(napi_env, napi_callback_info);
オブジェクトの寿命管理で説明されている理由がない限り、napi_callback
内でハンドルまたはコールバックスコープを作成する必要はありません。
node_api_nogc_finalize
#
外部で所有されているデータが、関連付けられていたオブジェクトがガベージコレクションされたためにクリーンアップできる状態になったときに、ユーザーに通知できるようにするアドオン提供関数の関数ポインタ型。ユーザーは、オブジェクトのコレクション時に呼び出される次のシグネチャを満たす関数を提供する必要があります。現在、node_api_nogc_finalize
は、外部データを持つオブジェクトがいつ収集されるかを調べるために使用できます。
typedef void (*node_api_nogc_finalize)(node_api_nogc_env env,
void* finalize_data,
void* finalize_hint);
オブジェクトのライフタイム管理で説明されている理由がない限り、関数本体内でハンドルやコールバックスコープを作成する必要はありません。
これらの関数は、JavaScriptエンジンがJavaScriptコードを実行できない状態のときに呼び出される可能性があるため、最初のパラメータとしてnode_api_nogc_env
を受け入れるNode-APIのみを呼び出すことができます。現在のガベージコレクションサイクルが完了した後に実行するために、JavaScriptエンジンの状態へのアクセスが必要なNode-API呼び出しをスケジュールするには、node_api_post_finalizer
を使用できます。
node_api_create_external_string_latin1
およびnode_api_create_external_string_utf16
の場合、外部文字列は環境シャットダウンの後期に収集される可能性があるため、env
パラメータはnullになる可能性があります。
変更履歴
-
実験的 (
NAPI_EXPERIMENTAL
)最初のパラメータとして
node_api_nogc_env
を受け入れるNode-APIのみを呼び出すことができます。そうしないと、アプリケーションは適切なエラーメッセージで終了します。この機能は、NODE_API_EXPERIMENTAL_NOGC_ENV_OPT_OUT
を定義することでオフにできます。
napi_finalize
#
ガベージコレクションイベントに応じて、ガベージコレクションサイクルが完了した後に、Node-APIへの一連の呼び出しをスケジュールできるようにする、アドオンが提供する関数への関数ポインタ型。これらの関数ポインタは、node_api_post_finalizer
で使用できます。
typedef void (*napi_finalize)(napi_env env,
void* finalize_data,
void* finalize_hint);
変更履歴
-
実験的 (
NAPI_EXPERIMENTAL
が定義されている場合)この型の関数は、
node_api_post_finalizer
以外では、ファイナライザーとして使用できなくなりました。代わりにnode_api_nogc_finalize
を使用する必要があります。この機能は、NODE_API_EXPERIMENTAL_NOGC_ENV_OPT_OUT
を定義することでオフにできます。
napi_async_execute_callback
#
非同期操作をサポートする関数で使用される関数ポインタ。コールバック関数は、次のシグネチャを満たす必要があります。
typedef void (*napi_async_execute_callback)(napi_env env, void* data);
この関数の実装では、JavaScriptを実行したり、JavaScriptオブジェクトと対話したりするNode-API呼び出しを避ける必要があります。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);
オブジェクトのライフタイム管理で説明されている理由がない限り、関数本体内でハンドルやコールバックスコープを作成する必要はありません。
napi_threadsafe_function_call_js
#
非同期スレッドセーフ関数呼び出しで使用される関数ポインタ。コールバックはメインスレッドで呼び出されます。その目的は、セカンダリスレッドからのキューを介して到着するデータ項目を使用して、通常はnapi_call_function
を介してJavaScriptへの呼び出しに必要なパラメータを構築し、JavaScriptへの呼び出しを行うことです。
セカンダリスレッドからキューを介して到着したデータは、data
パラメータで提供され、呼び出すJavaScript関数はjs_callback
パラメータで提供されます。
Node-APIは、このコールバックを呼び出す前に環境を設定するため、napi_make_callback
ではなく、napi_call_function
を介してJavaScript関数を呼び出すだけで十分です。
コールバック関数は、次のシグネチャを満たす必要があります。
typedef void (*napi_threadsafe_function_call_js)(napi_env env,
napi_value js_callback,
void* context,
void* data);
[in] env
: API呼び出しに使用する環境。スレッドセーフ関数の破棄中でdata
を解放する必要がある場合はNULL
。[in] js_callback
: 呼び出すJavaScript関数。スレッドセーフ関数の破棄中でdata
を解放する必要がある場合はNULL
。また、スレッドセーフ関数がjs_callback
なしで作成された場合もNULL
になる可能性があります。[in] context
: スレッドセーフ関数の作成に使用されたオプションデータ。[in] data
: セカンダリスレッドによって作成されたデータ。このネイティブデータをJavaScript値(Node-API関数を使用)に変換し、js_callback
が呼び出されたときにパラメータとして渡すのは、コールバックの責任です。このポインタは、スレッドとこのコールバックによって完全に管理されます。したがって、このコールバックはデータを解放する必要があります。
オブジェクトのライフタイム管理で説明されている理由がない限り、関数本体内でハンドルやコールバックスコープを作成する必要はありません。
napi_cleanup_hook
#
napi_add_env_cleanup_hook
で使用される関数ポインタ。環境が破棄されるときに呼び出されます。
コールバック関数は、次のシグネチャを満たす必要があります。
typedef void (*napi_cleanup_hook)(void* data);
[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);
[in] handle
: 非同期クリーンアップの完了後、napi_remove_async_cleanup_hook
に渡す必要があるハンドル。[in] data
:napi_add_async_cleanup_hook
に渡されたデータ。
関数の本体では、非同期クリーンアップアクションを開始し、その最後に、napi_remove_async_cleanup_hook
の呼び出しでhandle
を渡す必要があります。
エラー処理#
Node-APIでは、エラー処理に、戻り値とJavaScript例外の両方を使用します。次のセクションでは、それぞれのケースのアプローチについて説明します。
戻り値#
すべてのNode-API関数は、同じエラー処理パターンを共有しています。すべてのAPI関数の戻り型はnapi_status
です。
リクエストが成功し、キャッチされないJavaScript例外がスローされなかった場合、戻り値はnapi_ok
になります。エラーが発生し、例外がスローされた場合、エラーのnapi_status
値が返されます。例外がスローされ、エラーが発生しなかった場合、napi_pending_exception
が返されます。
napi_ok
またはnapi_pending_exception
以外の戻り値が返された場合は、例外が保留されているかどうかを確認するために、napi_is_exception_pending
を呼び出す必要があります。詳細については、例外に関するセクションを参照してください。
可能なnapi_status
値の完全なセットは、napi_api_types.h
で定義されています。
napi_status
戻り値は、発生したエラーのVMに依存しない表現を提供します。場合によっては、エラーを表す文字列やVM(エンジン)固有の情報など、より詳細な情報を取得できると便利です。
この情報を取得するために、napi_extended_error_info
構造体を返すnapi_get_last_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;
};
error_message
: 発生したエラーのテキスト表現。engine_reserved
: エンジン専用の予約された不透明ハンドル。engine_error_code
: VM固有のエラーコード。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_nogc_env env,
const napi_extended_error_info** result);
[in] env
: APIが呼び出される環境。[out] result
: エラーに関する詳細情報を含むnapi_extended_error_info
構造体。
APIが成功した場合はnapi_ok
を返します。
この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例外になる可能性があります。これは、JavaScriptの実行を引き起こさない可能性のあるAPI関数であっても同様です。
関数によって返されたnapi_status
がnapi_ok
の場合、例外は保留されておらず、追加のアクションは必要ありません。返されたnapi_status
がnapi_ok
またはnapi_pending_exception
以外のいずれかである場合、すぐに戻るのではなく、回復して続行するために、napi_is_exception_pending
を呼び出して、例外が保留されているかどうかを判断する必要があります。
多くの場合、Node-API関数が呼び出され、例外がすでに保留されている場合、関数はnapi_pending_exception
のnapi_status
ですぐに戻ります。ただし、これはすべての関数に当てはまるわけではありません。Node-APIでは、JavaScriptに戻る前に最小限のクリーンアップを許可するために、関数の一部を呼び出すことができます。その場合、napi_status
は関数のステータスを反映します。以前に保留中の例外は反映しません。混乱を避けるために、すべての関数呼び出し後にエラー状態を確認してください。
例外が保留中の場合は、次の2つのアプローチのいずれかを採用できます。
最初のアプローチは、適切なクリーンアップを行い、JavaScriptに実行を戻すことです。JavaScriptへの移行の一部として、ネイティブメソッドが呼び出されたJavaScriptコードの箇所で例外がスローされます。例外が保留されている間、ほとんどのNode-API呼び出しの動作は規定されておらず、多くの場合、単にnapi_pending_exception
を返すだけなので、できるだけ処理を少なくし、例外が処理できるJavaScriptに戻るようにしてください。
2番目のアプローチは、例外を処理しようとすることです。ネイティブコードが例外をキャッチし、適切なアクションを実行してから続行できる場合があります。これは、例外が安全に処理できることがわかっている特定のケースでのみ推奨されます。このような場合、napi_get_and_clear_last_exception
を使用して例外を取得し、クリアすることができます。成功した場合、resultには最後にスローされた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は、新しく作成されたJavaScriptのError
オブジェクトを参照するnapi_value
です。
Node.jsプロジェクトは、内部で生成されるすべてのエラーにエラーコードを追加しています。目標は、アプリケーションがすべてのエラーチェックにこれらのエラーコードを使用することです。関連するエラーメッセージは残りますが、ログと表示のみに使用されることを意図しており、メッセージはSemVerを適用せずに変更できると想定されます。Node-APIでこのモデルを(内部機能として、またモジュール固有の機能として(良い習慣として))サポートするために、throw_
およびcreate_
関数は、エラーオブジェクトに追加されるコードの文字列であるオプションのcodeパラメーターを受け取ります。オプションのパラメーターがNULL
の場合、エラーに関連付けられるコードはありません。コードが指定されている場合、エラーに関連付けられた名前も次のように更新されます。
originalName [code]
ここで、originalName
はエラーに関連付けられた元の名前であり、code
は提供されたコードです。たとえば、コードが'ERR_ERROR_1'
で、TypeError
が作成されている場合、名前は次のようになります。
TypeError [ERR_ERROR_1]
napi_throw
#
NAPI_EXTERN napi_status napi_throw(napi_env env, napi_value error);
[in] env
: APIが呼び出される環境。[in] error
: スローされるJavaScript値。
APIが成功した場合はnapi_ok
を返します。
このAPIは、指定されたJavaScript値をスローします。
napi_throw_error
#
NAPI_EXTERN napi_status napi_throw_error(napi_env env,
const char* code,
const char* msg);
[in] env
: APIが呼び出される環境。[in] code
: エラーに設定されるオプションのエラーコード。[in] msg
: エラーに関連付けられるテキストを表すC文字列。
APIが成功した場合はnapi_ok
を返します。
このAPIは、指定されたテキストを含むJavaScriptのError
をスローします。
napi_throw_type_error
#
NAPI_EXTERN napi_status napi_throw_type_error(napi_env env,
const char* code,
const char* msg);
[in] env
: APIが呼び出される環境。[in] code
: エラーに設定されるオプションのエラーコード。[in] msg
: エラーに関連付けられるテキストを表すC文字列。
APIが成功した場合はnapi_ok
を返します。
このAPIは、指定されたテキストを含むJavaScriptのTypeError
をスローします。
napi_throw_range_error
#
NAPI_EXTERN napi_status napi_throw_range_error(napi_env env,
const char* code,
const char* msg);
[in] env
: APIが呼び出される環境。[in] code
: エラーに設定されるオプションのエラーコード。[in] msg
: エラーに関連付けられるテキストを表すC文字列。
APIが成功した場合はnapi_ok
を返します。
この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);
[in] env
: APIが呼び出される環境。[in] code
: エラーに設定されるオプションのエラーコード。[in] msg
: エラーに関連付けられるテキストを表すC文字列。
APIが成功した場合はnapi_ok
を返します。
このAPIは、指定されたテキストを含むJavaScriptのSyntaxError
をスローします。
napi_is_error
#
NAPI_EXTERN napi_status napi_is_error(napi_env env,
napi_value value,
bool* result);
[in] env
: APIが呼び出される環境。[in] value
: チェックされるnapi_value
。[out] result
:napi_value
がエラーを表す場合はtrueに、それ以外の場合はfalseに設定されるブール値。
APIが成功した場合はnapi_ok
を返します。
この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);
[in] env
: APIが呼び出される環境。[in] code
: エラーに関連付けられるエラーコードの文字列を持つオプションのnapi_value
。[in] msg
:Error
のメッセージとして使用されるJavaScriptのstring
を参照するnapi_value
。[out] result
: 作成されたエラーを表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
この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);
[in] env
: APIが呼び出される環境。[in] code
: エラーに関連付けられるエラーコードの文字列を持つオプションのnapi_value
。[in] msg
:Error
のメッセージとして使用されるJavaScriptのstring
を参照するnapi_value
。[out] result
: 作成されたエラーを表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
この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);
[in] env
: APIが呼び出される環境。[in] code
: エラーに関連付けられるエラーコードの文字列を持つオプションのnapi_value
。[in] msg
:Error
のメッセージとして使用されるJavaScriptのstring
を参照するnapi_value
。[out] result
: 作成されたエラーを表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
この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);
[in] env
: APIが呼び出される環境。[in] code
: エラーに関連付けられるエラーコードの文字列を持つオプションのnapi_value
。[in] msg
:Error
のメッセージとして使用されるJavaScriptのstring
を参照するnapi_value
。[out] result
: 作成されたエラーを表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
このAPIは、指定されたテキストを含むJavaScriptのSyntaxError
を返します。
napi_get_and_clear_last_exception
#
napi_status napi_get_and_clear_last_exception(napi_env env,
napi_value* result);
[in] env
: APIが呼び出される環境。[out] result
: 保留中の例外がある場合は例外、それ以外の場合はNULL
。
APIが成功した場合はnapi_ok
を返します。
このAPIは、保留中のJavaScript例外がある場合でも呼び出すことができます。
napi_is_exception_pending
#
napi_status napi_is_exception_pending(napi_env env, bool* result);
[in] env
: APIが呼び出される環境。[out] result
: 例外が保留中の場合はtrueに設定されるブール値。
APIが成功した場合はnapi_ok
を返します。
このAPIは、保留中のJavaScript例外がある場合でも呼び出すことができます。
napi_fatal_exception
#
napi_status napi_fatal_exception(napi_env env, napi_value err);
[in] env
: APIが呼び出される環境。[in] err
:'uncaughtException'
に渡されるエラー。
JavaScriptで'uncaughtException'
をトリガーします。非同期コールバックが回復する方法のない例外をスローする場合に役立ちます。
致命的なエラー#
ネイティブアドオンで回復不能なエラーが発生した場合、致命的なエラーをスローしてプロセスをすぐに終了させることができます。
napi_fatal_error
#
NAPI_NO_RETURN void napi_fatal_error(const char* location,
size_t location_len,
const char* message,
size_t message_len);
[in] location
: エラーが発生したオプションの場所。[in] location_len
: 場所の長さ(バイト単位)。null終端の場合はNAPI_AUTO_LENGTH
。[in] message
: エラーに関連付けられたメッセージ。[in] message_len
: メッセージの長さ(バイト単位)。null終端の場合はNAPI_AUTO_LENGTH
。
関数呼び出しは戻らず、プロセスは終了します。
このAPIは、保留中のJavaScript例外がある場合でも呼び出すことができます。
オブジェクトのライフタイム管理#
Node-API呼び出しが行われると、基になるVMのヒープ内のオブジェクトへのハンドルが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
}
これにより、大量のハンドルが作成され、かなりのリソースが消費されます。さらに、ネイティブコードは最新のハンドルしか使用できませんが、関連付けられたすべてのオブジェクトも同じスコープを共有するため、ライブに保たれます。
このケースに対処するために、Node-APIは、新しく作成されたハンドルが関連付けられる新しい「スコープ」を確立する機能を提供します。これらのハンドルが不要になったら、スコープを「閉じる」ことができ、スコープに関連付けられたハンドルはすべて無効になります。スコープを開閉するために利用できるメソッドは、napi_open_handle_scope
とnapi_close_handle_scope
です。
Node-APIは、単一の入れ子になったスコープの階層のみをサポートしています。常にアクティブなスコープは1つだけであり、アクティブな間は、すべての新しいハンドルがそのスコープに関連付けられます。スコープは、開かれた順序とは逆の順序で閉じる必要があります。さらに、ネイティブメソッド内で作成されたすべてのスコープは、そのメソッドから戻る前に閉じる必要があります。
前の例を使用すると、napi_open_handle_scope
とnapi_close_handle_scope
への呼び出しを追加すると、ループの実行全体を通して最大で1つのハンドルが有効になることが保証されます。
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;
}
}
スコープをネストする場合、内側のスコープからのハンドルがそのスコープの寿命を超えて存在する必要がある場合があります。Node-API は、このケースをサポートするために「エスケープ可能なスコープ」をサポートしています。エスケープ可能なスコープを使用すると、1 つのハンドルを「昇格」させることができ、それによって現在のスコープから「エスケープ」し、ハンドルの寿命が現在のスコープから外側のスコープの寿命に変わります。
エスケープ可能なスコープを開閉するために使用できるメソッドは、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);
[in] env
: APIが呼び出される環境。[out] result
: 新しいスコープを表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
この API は、新しいスコープを開きます。
napi_close_handle_scope
#
NAPI_EXTERN napi_status napi_close_handle_scope(napi_env env,
napi_handle_scope scope);
[in] env
: APIが呼び出される環境。[in] scope
: 閉じるスコープを表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
この API は、渡されたスコープを閉じます。スコープは、作成された順序の逆順で閉じる必要があります。
このAPIは、保留中のJavaScript例外がある場合でも呼び出すことができます。
napi_open_escapable_handle_scope
#
NAPI_EXTERN napi_status
napi_open_escapable_handle_scope(napi_env env,
napi_handle_scope* result);
[in] env
: APIが呼び出される環境。[out] result
: 新しいスコープを表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
この API は、1 つのオブジェクトを外側のスコープに昇格させることができる新しいスコープを開きます。
napi_close_escapable_handle_scope
#
NAPI_EXTERN napi_status
napi_close_escapable_handle_scope(napi_env env,
napi_handle_scope scope);
[in] env
: APIが呼び出される環境。[in] scope
: 閉じるスコープを表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
この 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);
[in] env
: APIが呼び出される環境。[in] scope
: 現在のスコープを表すnapi_value
。[in] escapee
: エスケープする JavaScriptObject
を表すnapi_value
。[out] result
: 外側のスコープ内のエスケープされたObject
へのハンドルを表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
この API は、JavaScript オブジェクトへのハンドルを昇格させ、外側のスコープの寿命の間有効にします。スコープごとに 1 回しか呼び出すことができません。複数回呼び出すとエラーが返されます。
このAPIは、保留中のJavaScript例外がある場合でも呼び出すことができます。
ネイティブメソッドの寿命よりも長い寿命を持つ値への参照#
場合によっては、アドオンが単一のネイティブメソッドの呼び出しよりも長い寿命を持つ値を作成して参照できるようにする必要があります。たとえば、コンストラクタを作成し、後でインスタンスを作成するリクエストでそのコンストラクタを使用するには、多くの異なるインスタンス作成リクエストでコンストラクタオブジェクトを参照できる必要があります。これは、前のセクションで説明したように、napi_value
として返される通常のハンドルでは不可能です。通常のハンドルの寿命はスコープによって管理され、ネイティブメソッドの終了前にすべてのスコープを閉じる必要があります。
Node-API は、値への永続的な参照を作成するためのメソッドを提供します。現在、Node-API では、オブジェクト、外部、関数、シンボルを含む、限られた値タイプに対してのみ参照を作成できます。
各参照には、0 以上の値を持つ関連付けられたカウントがあり、参照が対応する値を存続させるかどうかを決定します。カウントが 0 の参照は、値が収集されるのを防ぎません。オブジェクト (オブジェクト、関数、外部) およびシンボル型の値は「弱い」参照になり、収集されていない間もアクセスできます。カウントが 0 より大きいと、値が収集されるのを防ぎます。
シンボル値には異なる種類があります。真の弱い参照の動作は、napi_create_symbol
関数または JavaScript Symbol()
コンストラクタの呼び出しで作成されたローカルシンボルでのみサポートされています。node_api_symbol_for
関数または JavaScript Symbol.for()
関数の呼び出しで作成されたグローバルに登録されたシンボルは、ガベージコレクタがそれらを収集しないため、常に強い参照のままです。Symbol.iterator
などの既知のシンボルも同様です。これらもガベージコレクタによって収集されることはありません。
参照は、初期参照カウントを使用して作成できます。その後、カウントは napi_reference_ref
および napi_reference_unref
を介して変更できます。参照のカウントが 0 の間にオブジェクトが収集された場合、参照に関連付けられたオブジェクトを取得するための後続のすべての呼び出し napi_get_reference_value
は、返された napi_value
に対して NULL
を返します。オブジェクトが収集された参照に対して napi_reference_ref
を呼び出そうとすると、エラーが発生します。
参照は、アドオンで不要になったら削除する必要があります。参照が削除されると、対応するオブジェクトが収集されるのを防ぐことはなくなります。永続的な参照を削除しないと、永続的な参照のネイティブメモリとヒープ上の対応するオブジェクトの両方が永久に保持される「メモリリーク」が発生します。
同じオブジェクトを参照する複数の永続的な参照を作成できます。それぞれが個々のカウントに基づいてオブジェクトを存続させるかどうかを決定します。同じオブジェクトへの複数の永続的な参照は、予期せずネイティブメモリを存続させる可能性があります。永続的な参照のネイティブ構造は、参照されるオブジェクトのファイナライザが実行されるまで存続させておく必要があります。同じオブジェクトに対して新しい永続的な参照が作成された場合、そのオブジェクトのファイナライザは実行されず、以前の永続的な参照によって示されるネイティブメモリは解放されません。これは、可能な場合は napi_reference_unref
に加えて napi_delete_reference
を呼び出すことで回避できます。
変更履歴
-
実験的 (
NAPI_EXPERIMENTAL
が定義されている場合)参照はすべての値タイプに対して作成できます。新しくサポートされる値タイプは弱い参照セマンティクスをサポートしておらず、これらのタイプの値は参照カウントが 0 になると解放され、参照からアクセスできなくなります。
napi_create_reference
#
NAPI_EXTERN napi_status napi_create_reference(napi_env env,
napi_value value,
uint32_t initial_refcount,
napi_ref* result);
[in] env
: APIが呼び出される環境。[in] value
: 参照が作成されるnapi_value
。[in] initial_refcount
: 新しい参照の初期参照カウント。[out] result
: 新しい参照を指すnapi_ref
。
APIが成功した場合はnapi_ok
を返します。
この API は、渡された値への指定された参照カウントを持つ新しい参照を作成します。
napi_delete_reference
#
NAPI_EXTERN napi_status napi_delete_reference(napi_env env, napi_ref ref);
[in] env
: APIが呼び出される環境。[in] ref
: 削除するnapi_ref
。
APIが成功した場合はnapi_ok
を返します。
この API は、渡された参照を削除します。
このAPIは、保留中のJavaScript例外がある場合でも呼び出すことができます。
napi_reference_ref
#
NAPI_EXTERN napi_status napi_reference_ref(napi_env env,
napi_ref ref,
uint32_t* result);
[in] env
: APIが呼び出される環境。[in] ref
: 参照カウントが増加するnapi_ref
。[out] result
: 新しい参照カウント。
APIが成功した場合はnapi_ok
を返します。
この API は、渡された参照の参照カウントをインクリメントし、結果の参照カウントを返します。
napi_reference_unref
#
NAPI_EXTERN napi_status napi_reference_unref(napi_env env,
napi_ref ref,
uint32_t* result);
[in] env
: APIが呼び出される環境。[in] ref
: 参照カウントがデクリメントされるnapi_ref
。[out] result
: 新しい参照カウント。
APIが成功した場合はnapi_ok
を返します。
この API は、渡された参照の参照カウントをデクリメントし、結果の参照カウントを返します。
napi_get_reference_value
#
NAPI_EXTERN napi_status napi_get_reference_value(napi_env env,
napi_ref ref,
napi_value* result);
[in] env
: APIが呼び出される環境。[in] ref
: 対応する値が要求されるnapi_ref
。[out] result
:napi_ref
によって参照されるnapi_value
。
APIが成功した場合はnapi_ok
を返します。
まだ有効な場合、この API は napi_ref
に関連付けられた JavaScript 値を表す napi_value
を返します。それ以外の場合、result は 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_nogc_env env,
napi_cleanup_hook fun,
void* arg);
現在の Node.js 環境が終了したときに、arg
パラメータを使用して実行される関数として fun
を登録します。
関数は、異なる 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_nogc_env env,
void (*fun)(void* arg),
void* arg);
現在の Node.js 環境が終了したときに、arg
パラメータを使用して実行される関数として fun
の登録を解除します。引数と関数値の両方が完全に一致する必要があります。
関数は、元々 napi_add_env_cleanup_hook
で登録されている必要があります。そうでない場合、プロセスは中止されます。
napi_add_async_cleanup_hook
#
NAPI_EXTERN napi_status napi_add_async_cleanup_hook(
node_api_nogc_env env,
napi_async_cleanup_hook hook,
void* arg,
napi_async_cleanup_hook_handle* remove_handle);
[in] env
: APIが呼び出される環境。[in] hook
: 環境の破棄時に呼び出す関数ポインタ。[in] arg
:hook
が呼び出される際に渡されるポインター。[out] remove_handle
: 非同期クリーンアップフックを参照するオプションのハンドル。
現在の Node.js 環境が終了した際に、remove_handle
パラメーターと arg
パラメーターとともに実行される関数として、napi_async_cleanup_hook
型の関数である hook
を登録します。
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);
[in] remove_handle
:napi_add_async_cleanup_hook
で作成された非同期クリーンアップフックへのハンドル。
remove_handle
に対応するクリーンアップフックの登録を解除します。これにより、フックが既に実行を開始している場合を除き、フックの実行が防止されます。これは、napi_add_async_cleanup_hook
から取得したすべての napi_async_cleanup_hook_handle
値に対して呼び出す必要があります。
Node.js 環境終了時のファイナライゼーション#
Node.js 環境は、worker.terminate()
のリクエストのように、JavaScript の実行が禁止され次第、可能な限り任意のタイミングで破棄される可能性があります。環境が破棄されると、JavaScript オブジェクト、スレッドセーフ関数、および環境インスタンスデータに登録された napi_finalize
コールバックが、直ちに個別で呼び出されます。
napi_finalize
コールバックの呼び出しは、手動で登録されたクリーンアップフックの後でスケジュールされます。環境シャットダウン中のアドオンのファイナライゼーションの適切な順序を確保し、napi_finalize
コールバックでの use-after-free を回避するために、アドオンは napi_add_env_cleanup_hook
および napi_add_async_cleanup_hook
を使用してクリーンアップフックを登録し、割り当てられたリソースを適切な順序で手動で解放する必要があります。
モジュールの登録#
Node-API モジュールは、NODE_MODULE
マクロを使用する代わりに、以下の方法を使用することを除いて、他のモジュールと同様の方法で登録されます。
NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
次の違いは、Init
メソッドのシグネチャです。Node-API モジュールの場合、以下のようになります。
napi_value Init(napi_env env, napi_value exports);
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;
}
アドオンの 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;
}
新しいインスタンスを作成できるようにクラスを定義するには(多くの場合、Object wrap と共に使用されます)
// 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;
}
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;
}
パラメーター env
および exports
は、NAPI_MODULE_INIT
マクロの本体に提供されます。
すべての Node-API アドオンはコンテキスト対応であり、複数回ロードされる可能性があります。そのようなモジュールを宣言する際には、いくつかの設計上の考慮事項があります。コンテキスト対応アドオンに関するドキュメントで、詳細を確認してください。
変数 env
および exports
は、マクロ呼び出しに続く関数本体内で使用できます。
オブジェクトのプロパティの設定に関する詳細については、JavaScript プロパティの操作に関するセクションを参照してください。
アドオンモジュールの構築に関する一般的な詳細については、既存の API を参照してください。
JavaScript 値の操作#
Node-API は、すべての種類の JavaScript 値を作成するための一連の API を公開しています。これらの型のいくつかは、ECMAScript 言語仕様のセクション 6 でドキュメント化されています。
基本的に、これらの API は次のいずれかを行うために使用されます。
- 新しい JavaScript オブジェクトを作成する
- プリミティブ C 型から Node-API 値に変換する
- Node-API 値からプリミティブ C 型に変換する
undefined
およびnull
を含むグローバルインスタンスを取得する
Node-API 値は、型 napi_value
で表されます。JavaScript 値を必要とするすべての Node-API 呼び出しは、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;
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;
プロパティフィルタービット。それらは、合成フィルターを構築するために or 演算子で結合できます。
napi_key_conversion
#
typedef enum {
napi_key_keep_numbers,
napi_key_numbers_to_strings
} napi_key_conversion;
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;
napi_value
の型を記述します。これは一般的に、ECMAScript 言語仕様のセクション 6.1 で説明されている型に対応します。そのセクションの型に加えて、napi_valuetype
は外部データを持つ Function
と Object
も表すことができます。
型 napi_external
の JavaScript 値は、プロパティを設定できず、プロトタイプがないプレーンなオブジェクトとして 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;
これは、TypedArray
の基になるバイナリスカラーデータ型を表します。この列挙型の要素は、ECMAScript 言語仕様のセクション 22.2 に対応します。
オブジェクト作成関数#
napi_create_array
#
napi_status napi_create_array(napi_env env, napi_value* result)
[in] env
: Node-API呼び出しが実行される環境。[out] result
: JavaScript のArray
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
この API は、JavaScript の Array
型に対応する Node-API 値を返します。JavaScript 配列は、ECMAScript 言語仕様のセクション 22.1で説明されています。
napi_create_array_with_length
#
napi_status napi_create_array_with_length(napi_env env,
size_t length,
napi_value* result)
[in] env
: APIが呼び出される環境。[in] length
:Array
の初期の長さ。[out] result
: JavaScript のArray
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
この API は、JavaScript の Array
型に対応する Node-API 値を返します。Array
の length プロパティは、渡された length パラメーターに設定されます。ただし、配列が作成されるときに、基になるバッファーが VM によって事前割り当てられることは保証されていません。その動作は、基になる VM 実装に任されています。バッファーが、C を介して直接読み書きできる連続したメモリブロックである必要がある場合は、napi_create_external_arraybuffer
の使用を検討してください。
JavaScript 配列は、ECMAScript 言語仕様のセクション 22.1で説明されています。
napi_create_arraybuffer
#
napi_status napi_create_arraybuffer(napi_env env,
size_t byte_length,
void** data,
napi_value* result)
[in] env
: APIが呼び出される環境。[in] length
: 作成する配列バッファーの長さ(バイト単位)。[out] data
:ArrayBuffer
の基になるバイトバッファーへのポインター。data
は、NULL
を渡すことでオプションで無視できます。[out] result
: JavaScript のArrayBuffer
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
この API は、JavaScript の ArrayBuffer
に対応する Node-API 値を返します。ArrayBuffer
は、固定長のバイナリデータバッファーを表すために使用されます。通常、これらは TypedArray
オブジェクトのバッキングバッファーとして使用されます。割り当てられた ArrayBuffer
は、渡された length
パラメーターによってサイズが決まる、基になるバイトバッファーを持ちます。呼び出し元がバッファーを直接操作する場合に備えて、基になるバッファーはオプションで呼び出し元に返されます。このバッファーは、ネイティブコードから直接書き込むことしかできません。JavaScript からこのバッファーに書き込むには、型付き配列または DataView
オブジェクトを作成する必要があります。
JavaScript ArrayBuffer
オブジェクトは、ECMAScript 言語仕様のセクション 24.1で説明されています。
napi_create_buffer
#
napi_status napi_create_buffer(napi_env env,
size_t size,
void** data,
napi_value* result)
[in] env
: APIが呼び出される環境。[in] size
: 基になるバッファーのサイズ(バイト単位)。[out] data
: 基になるバッファーへの生のポインター。data
は、NULL
を渡すことでオプションで無視できます。[out] result
:node::Buffer
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
この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)
[in] env
: APIが呼び出される環境。[in] size
: 入力バッファのサイズ(バイト単位)(新しいバッファのサイズと同じである必要があります)。[in] data
: コピー元の基になるバッファへの生のポインタ。[out] result_data
: 新しいBuffer
の基になるデータバッファへのポインタ。result_data
は、NULL
を渡すことでオプションで無視できます。[out] result
:node::Buffer
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
このAPIは、node::Buffer
オブジェクトを割り当て、渡されたバッファからコピーしたデータで初期化します。これは引き続き完全にサポートされているデータ構造ですが、ほとんどの場合、TypedArray
を使用すれば十分です。
napi_create_date
#
napi_status napi_create_date(napi_env env,
double time,
napi_value* result);
[in] env
: APIが呼び出される環境。[in] time
: 1970年1月1日UTCからのミリ秒単位のECMAScript時間値。[out] result
: JavaScriptのDate
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
このAPIはうるう秒を考慮しません。ECMAScriptはPOSIX時間仕様に準拠しているため、無視されます。
このAPIは、JavaScriptのDate
オブジェクトを割り当てます。
JavaScriptのDate
オブジェクトについては、ECMAScript言語仕様のセクション20.3で説明されています。
napi_create_external
#
napi_status napi_create_external(napi_env env,
void* data,
napi_finalize finalize_cb,
void* finalize_hint,
napi_value* result)
[in] env
: APIが呼び出される環境。[in] data
: 外部データへの生のポインタ。[in] finalize_cb
: 外部値が収集されるときに呼び出すオプションのコールバック。napi_finalize
で詳細を説明しています。[in] finalize_hint
: コレクション中にfinalizeコールバックに渡すオプションのヒント。[out] result
: 外部値を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
このAPIは、外部データが添付されたJavaScript値を割り当てます。これは、JavaScriptコードを通じて外部データを渡し、後でnapi_get_value_external
を使用してネイティブコードで取得できるようにするために使用されます。
このAPIは、作成されたJavaScriptオブジェクトがガベージコレクションされたときに呼び出されるnapi_finalize
コールバックを追加します。
作成された値はオブジェクトではないため、追加のプロパティはサポートされていません。これは異なる値の型と見なされます。外部値を使用して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)
[in] env
: APIが呼び出される環境。[in] external_data
:ArrayBuffer
の基になるバイトバッファへのポインタ。[in] byte_length
: 基になるバッファのバイト単位の長さ。[in] finalize_cb
:ArrayBuffer
が収集されるときに呼び出すオプションのコールバック。napi_finalize
で詳細を説明しています。[in] finalize_hint
: コレクション中にfinalizeコールバックに渡すオプションのヒント。[out] result
: JavaScript のArrayBuffer
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
Node.js以外のいくつかのランタイムでは、外部バッファのサポートが終了しています。Node.js以外のランタイムでは、外部バッファがサポートされていないことを示すために、このメソッドがnapi_no_external_buffers_allowed
を返す場合があります。このようなランタイムの1つは、electron/issues/35801で説明されているように、Electronです。
すべてのランタイムとの幅広い互換性を維持するために、node-apiヘッダーを含める前に、アドオンでNODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
を定義できます。そうすることで、外部バッファを作成する2つの関数が非表示になります。これにより、これらのメソッドの1つを誤って使用した場合にコンパイルエラーが発生することが保証されます。
このAPIは、JavaScriptのArrayBuffer
に対応するNode-API値を返します。ArrayBuffer
の基になるバイトバッファは外部で割り当てられ、管理されます。呼び出し元は、finalizeコールバックが呼び出されるまで、バイトバッファが有効なままであることを保証する必要があります。
このAPIは、作成されたJavaScriptオブジェクトがガベージコレクションされたときに呼び出されるnapi_finalize
コールバックを追加します。
JavaScriptのArrayBuffer
については、ECMAScript言語仕様のセクション24.1で説明されています。
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)
[in] env
: APIが呼び出される環境。[in] length
: 入力バッファのサイズ(バイト単位)(新しいバッファのサイズと同じである必要があります)。[in] data
: JavaScriptに公開する基になるバッファへの生のポインタ。[in] finalize_cb
:ArrayBuffer
が収集されるときに呼び出すオプションのコールバック。napi_finalize
で詳細を説明しています。[in] finalize_hint
: コレクション中にfinalizeコールバックに渡すオプションのヒント。[out] result
:node::Buffer
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
Node.js以外のいくつかのランタイムでは、外部バッファのサポートが終了しています。Node.js以外のランタイムでは、外部バッファがサポートされていないことを示すために、このメソッドがnapi_no_external_buffers_allowed
を返す場合があります。このようなランタイムの1つは、electron/issues/35801で説明されているように、Electronです。
すべてのランタイムとの幅広い互換性を維持するために、node-apiヘッダーを含める前に、アドオンでNODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
を定義できます。そうすることで、外部バッファを作成する2つの関数が非表示になります。これにより、これらのメソッドの1つを誤って使用した場合にコンパイルエラーが発生することが保証されます。
このAPIは、node::Buffer
オブジェクトを割り当て、渡されたバッファによってバッキングされたデータで初期化します。これは引き続き完全にサポートされているデータ構造ですが、ほとんどの場合、TypedArray
を使用すれば十分です。
このAPIは、作成されたJavaScriptオブジェクトがガベージコレクションされたときに呼び出されるnapi_finalize
コールバックを追加します。
Node.js >=4の場合、Buffers
はUint8Array
です。
napi_create_object
#
napi_status napi_create_object(napi_env env, napi_value* result)
[in] env
: APIが呼び出される環境。[out] result
: JavaScriptのObject
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
このAPIは、デフォルトのJavaScriptのObject
を割り当てます。これは、JavaScriptでnew Object()
を実行するのと同じです。
JavaScriptのObject
型については、ECMAScript言語仕様のセクション6.1.7で説明されています。
napi_create_symbol
#
napi_status napi_create_symbol(napi_env env,
napi_value description,
napi_value* result)
[in] env
: APIが呼び出される環境。[in] description
: シンボルの説明として設定されるJavaScriptのstring
を参照するオプションのnapi_value
。[out] result
: JavaScriptのsymbol
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
このAPIは、UTF8エンコードされたC文字列からJavaScriptのsymbol
値を作成します。
JavaScriptのsymbol
型については、ECMAScript言語仕様のセクション19.4で説明されています。
node_api_symbol_for
#
napi_status node_api_symbol_for(napi_env env,
const char* utf8description,
size_t length,
napi_value* result)
[in] env
: APIが呼び出される環境。[in] utf8description
: シンボルの説明として使用されるテキストを表すUTF-8 C文字列。[in] length
: 説明文字列の長さ(バイト単位)、またはnullで終了する場合はNAPI_AUTO_LENGTH
。[out] result
: JavaScriptのsymbol
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
このAPIは、指定された説明を持つ既存のシンボルをグローバルレジストリで検索します。シンボルが既に存在する場合はそれが返され、それ以外の場合は新しいシンボルがレジストリに作成されます。
JavaScriptのsymbol
型については、ECMAScript言語仕様のセクション19.4で説明されています。
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)
[in] env
: APIが呼び出される環境。[in] type
:TypedArray
内の要素のスカラーデータ型。[in] length
:TypedArray
内の要素の数。[in] arraybuffer
: 型付き配列の基になるArrayBuffer
。[in] byte_offset
:TypedArray
の投影を開始するArrayBuffer
内のバイトオフセット。[out] result
: JavaScriptのTypedArray
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
このAPIは、既存のArrayBuffer
の上にJavaScriptのTypedArray
オブジェクトを作成します。TypedArray
オブジェクトは、各要素が同じ基になるバイナリスカラーデータ型を持つ、基になるデータバッファ上の配列のようなビューを提供します。
(length * size_of_element) + byte_offset
が、渡された配列のバイト単位のサイズ以下である必要があります。そうでない場合は、RangeError
例外が発生します。
JavaScriptのTypedArray
オブジェクトについては、ECMAScript言語仕様のセクション22.2で説明されています。
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)
[in] env
: APIが呼び出される環境。[in] length
:DataView
内の要素の数。[in] arraybuffer
:DataView
の基になるArrayBuffer
。[in] byte_offset
:DataView
の投影を開始するArrayBuffer
内のバイトオフセット。[out] result
: JavaScriptのDataView
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
このAPIは、既存のArrayBuffer
の上にJavaScriptのDataView
オブジェクトを作成します。DataView
オブジェクトは、基になるデータバッファ上の配列のようなビューを提供しますが、ArrayBuffer
内で異なるサイズと型の項目を許可するビューです。
byte_length + byte_offset
が、渡された配列のバイト単位のサイズ以下である必要があります。そうでない場合は、RangeError
例外が発生します。
JavaScriptのDataView
オブジェクトについては、ECMAScript言語仕様のセクション24.3で説明されています。
C型からNode-APIに変換する関数#
napi_create_int32
#
napi_status napi_create_int32(napi_env env, int32_t value, napi_value* result)
[in] env
: APIが呼び出される環境。[in] value
: JavaScriptで表現される整数値。[out] result
: JavaScriptのnumber
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
このAPIは、Cのint32_t
型からJavaScriptのnumber
型に変換するために使用されます。
JavaScriptのnumber
型については、ECMAScript言語仕様のセクション6.1.6で説明されています。
napi_create_uint32
#
napi_status napi_create_uint32(napi_env env, uint32_t value, napi_value* result)
[in] env
: APIが呼び出される環境。[in] value
: JavaScriptで表現される符号なし整数値。[out] result
: JavaScriptのnumber
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
このAPIは、Cのuint32_t
型からJavaScriptのnumber
型に変換するために使用されます。
JavaScriptのnumber
型については、ECMAScript言語仕様のセクション6.1.6で説明されています。
napi_create_int64
#
napi_status napi_create_int64(napi_env env, int64_t value, napi_value* result)
[in] env
: APIが呼び出される環境。[in] value
: JavaScriptで表現される整数値。[out] result
: JavaScriptのnumber
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
このAPIは、Cのint64_t
型からJavaScriptのnumber
型に変換するために使用されます。
JavaScriptのnumber
型については、ECMAScript言語仕様のセクション6.1.6で説明されています。JavaScriptでは、int64_t
の完全な範囲を完全な精度で表現できないことに注意してください。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)
[in] env
: APIが呼び出される環境。[in] value
: JavaScriptで表現される倍精度値。[out] result
: JavaScriptのnumber
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
このAPIは、Cのdouble
型からJavaScriptのnumber
型に変換するために使用されます。
JavaScriptのnumber
型については、ECMAScript言語仕様のセクション6.1.6で説明されています。
napi_create_bigint_int64
#
napi_status napi_create_bigint_int64(napi_env env,
int64_t value,
napi_value* result);
[in] env
: APIが呼び出される環境。[in] value
: JavaScriptで表現される整数値。[out] result
: JavaScriptのBigInt
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
この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);
[in] env
: APIが呼び出される環境。[in] value
: JavaScriptで表現される符号なし整数値。[out] result
: JavaScriptのBigInt
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
この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);
[in] env
: APIが呼び出される環境。[in] sign_bit
: 結果のBigInt
が正または負になるかを決定します。[in] word_count
:words
配列の長さ。[in] words
:uint64_t
リトルエンディアン64ビットワードの配列。[out] result
: JavaScriptのBigInt
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
この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);
[in] env
: APIが呼び出される環境。[in] str
: ISO-8859-1エンコードされた文字列を表す文字バッファ。[in] length
: 文字列の長さ(バイト単位)。null終端の場合はNAPI_AUTO_LENGTH
。[out] result
: JavaScriptのstring
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
このAPIは、ISO-8859-1エンコードされたC文字列からJavaScriptのstring
値を生成します。ネイティブ文字列はコピーされます。
JavaScriptのstring
型は、ECMAScript言語仕様のセクション6.1.4で説明されています。
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);
[in] env
: APIが呼び出される環境。[in] str
: ISO-8859-1エンコードされた文字列を表す文字バッファ。[in] length
: 文字列の長さ(バイト単位)。null終端の場合はNAPI_AUTO_LENGTH
。[in] finalize_callback
: 文字列が収集されるときに呼び出す関数。この関数は、以下のパラメータで呼び出されます。[in] env
: アドオンが実行されている環境。文字列がワーカーまたはメインのNode.jsインスタンスの終了の一部として収集されている場合、この値はnullになる可能性があります。[in] data
: これは、void*
ポインタとしての値str
です。[in] finalize_hint
: これは、APIに与えられた値finalize_hint
です。napi_finalize
で詳細を確認できます。このパラメータはオプションです。null値を渡すことは、対応するJavaScript文字列が収集されたときにアドオンに通知する必要がないことを意味します。
[in] finalize_hint
: コレクション中にfinalizeコールバックに渡すオプションのヒント。[out] result
: JavaScriptのstring
を表すnapi_value
。[out] copied
: 文字列がコピーされたかどうか。コピーされた場合、ファイナライザはすでにstr
を破棄するために呼び出されています。
APIが成功した場合はnapi_ok
を返します。
このAPIは、ISO-8859-1エンコードされたC文字列からJavaScriptのstring
値を生成します。ネイティブ文字列はコピーされない可能性があり、したがってJavaScript値のライフサイクル全体にわたって存在する必要があります。
JavaScriptのstring
型は、ECMAScript言語仕様のセクション6.1.4で説明されています。
napi_create_string_utf16
#
napi_status napi_create_string_utf16(napi_env env,
const char16_t* str,
size_t length,
napi_value* result)
[in] env
: APIが呼び出される環境。[in] str
: UTF16-LEエンコードされた文字列を表す文字バッファ。[in] length
: 文字列の長さ(2バイトコード単位)。null終端の場合はNAPI_AUTO_LENGTH
。[out] result
: JavaScriptのstring
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
このAPIは、UTF16-LEエンコードされたC文字列からJavaScriptのstring
値を生成します。ネイティブ文字列はコピーされます。
JavaScriptのstring
型は、ECMAScript言語仕様のセクション6.1.4で説明されています。
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);
[in] env
: APIが呼び出される環境。[in] str
: UTF16-LEエンコードされた文字列を表す文字バッファ。[in] length
: 文字列の長さ(2バイトコード単位)。null終端の場合はNAPI_AUTO_LENGTH
。[in] finalize_callback
: 文字列が収集されるときに呼び出す関数。この関数は、以下のパラメータで呼び出されます。[in] env
: アドオンが実行されている環境。文字列がワーカーまたはメインのNode.jsインスタンスの終了の一部として収集されている場合、この値はnullになる可能性があります。[in] data
: これは、void*
ポインタとしての値str
です。[in] finalize_hint
: これは、APIに与えられた値finalize_hint
です。napi_finalize
で詳細を確認できます。このパラメータはオプションです。null値を渡すことは、対応するJavaScript文字列が収集されたときにアドオンに通知する必要がないことを意味します。
[in] finalize_hint
: コレクション中にfinalizeコールバックに渡すオプションのヒント。[out] result
: JavaScriptのstring
を表すnapi_value
。[out] copied
: 文字列がコピーされたかどうか。コピーされた場合、ファイナライザはすでにstr
を破棄するために呼び出されています。
APIが成功した場合はnapi_ok
を返します。
このAPIは、UTF16-LEエンコードされたC文字列からJavaScriptのstring
値を生成します。ネイティブ文字列はコピーされない可能性があり、したがってJavaScript値のライフサイクル全体にわたって存在する必要があります。
JavaScriptのstring
型は、ECMAScript言語仕様のセクション6.1.4で説明されています。
napi_create_string_utf8
#
napi_status napi_create_string_utf8(napi_env env,
const char* str,
size_t length,
napi_value* result)
[in] env
: APIが呼び出される環境。[in] str
: UTF8エンコードされた文字列を表す文字バッファ。[in] length
: 文字列の長さ(バイト単位)。null終端の場合はNAPI_AUTO_LENGTH
。[out] result
: JavaScriptのstring
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
このAPIは、UTF8エンコードされたC文字列からJavaScriptのstring
値を生成します。ネイティブ文字列はコピーされます。
JavaScriptのstring
型は、ECMAScript言語仕様のセクション6.1.4で説明されています。
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);
[in] env
: APIが呼び出される環境。[in] str
: UTF16-LEエンコードされた文字列を表す文字バッファ。[in] length
: 文字列の長さ(2バイトコード単位)。null終端の場合はNAPI_AUTO_LENGTH
。[out] result
: オブジェクトのプロパティキーとして使用される最適化されたJavaScriptのstring
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
このAPIは、オブジェクトのプロパティキーとして使用される最適化されたJavaScriptのstring
値を、UTF16-LEエンコードされたC文字列から生成します。ネイティブ文字列はコピーされます。
V8を含む多くのJavaScriptエンジンは、プロパティ値を設定および取得するためのキーとして内部化された文字列を使用しています。通常、ハッシュテーブルを使用して、そのような文字列を作成および検索します。キーの作成ごとに多少のコストがかかりますが、文字列全体ではなく文字列ポインタの比較を可能にすることで、その後のパフォーマンスが向上します。
新しいJavaScript文字列をプロパティキーとして使用する場合、一部のJavaScriptエンジンではnode_api_create_property_key_utf16
関数を使用する方が効率的です。それ以外の場合は、napi_create_string_utf16
またはnode_api_create_external_string_utf16
関数を使用してください。この方法で文字列を作成/保存する際に、追加のオーバーヘッドが発生する可能性があるためです。
JavaScriptのstring
型は、ECMAScript言語仕様のセクション6.1.4で説明されています。
Node-APIからC型に変換する関数#
napi_get_array_length
#
napi_status napi_get_array_length(napi_env env,
napi_value value,
uint32_t* result)
[in] env
: APIが呼び出される環境。[in] value
: 長さをクエリしているJavaScriptのArray
を表すnapi_value
。[out] result
: 配列の長さを表すuint32
。
APIが成功した場合はnapi_ok
を返します。
このAPIは、配列の長さを返します。
Array
の長さは、ECMAScript言語仕様のセクション22.1.4.1で説明されています。
napi_get_arraybuffer_info
#
napi_status napi_get_arraybuffer_info(napi_env env,
napi_value arraybuffer,
void** data,
size_t* byte_length)
[in] env
: APIが呼び出される環境。[in] arraybuffer
: クエリしているArrayBuffer
を表すnapi_value
。[out] data
:ArrayBuffer
の基になるデータバッファ。byte_lengthが0
の場合、これはNULL
またはその他のポインタ値になる可能性があります。[out] byte_length
: 基になるデータバッファの長さ(バイト単位)。
APIが成功した場合はnapi_ok
を返します。
このAPIは、ArrayBuffer
の基になるデータバッファとその長さを取得するために使用されます。
警告: このAPIを使用する際には注意してください。基になるデータバッファのライフタイムは、返された後でもArrayBuffer
によって管理されます。このAPIを使用する可能性のある安全な方法は、napi_create_reference
と組み合わせて使用することです。これは、ArrayBuffer
のライフタイムの制御を保証するために使用できます。また、他のGCをトリガーする可能性のあるAPIを呼び出さない限り、同じコールバック内で返されたデータバッファを使用することも安全です。
napi_get_buffer_info
#
napi_status napi_get_buffer_info(napi_env env,
napi_value value,
void** data,
size_t* length)
[in] env
: APIが呼び出される環境。[in] value
: クエリしているnode::Buffer
またはUint8Array
を表すnapi_value
。[out] data
:node::Buffer
またはUint8Array
の基になるデータバッファ。lengthが0
の場合、これはNULL
またはその他のポインタ値になる可能性があります。[out] length
: 基になるデータバッファの長さ(バイト単位)。
APIが成功した場合はnapi_ok
を返します。
このメソッドは、napi_get_typedarray_info
と同じdata
とbyte_length
を返します。また、napi_get_typedarray_info
は、値としてnode::Buffer
(Uint8Array)も受け入れます。
このAPIは、node::Buffer
の基になるデータバッファとその長さを取得するために使用されます。
警告: 基になるデータバッファのライフタイムがVMによって管理されている場合、保証されないため、このAPIを使用する際には注意してください。
napi_get_prototype
#
napi_status napi_get_prototype(napi_env env,
napi_value object,
napi_value* result)
[in] env
: APIが呼び出される環境。[in] object
: プロトタイプを返すJavaScriptのObject
を表すnapi_value
。これは、Object.getPrototypeOf
(関数のprototype
プロパティと同じではありません)と同等のものを返します。[out] result
: 指定されたオブジェクトのプロトタイプを表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
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)
[in] env
: APIが呼び出される環境。[in] typedarray
: プロパティをクエリするTypedArray
を表すnapi_value
。[out] type
:TypedArray
内の要素のスカラーデータ型。[out] length
:TypedArray
内の要素の数。[out] data
:TypedArray
の最初の要素を指すようにbyte_offset
値で調整されたTypedArray
の基になるデータバッファ。配列の長さが0
の場合、これはNULL
またはその他のポインタ値になる可能性があります。[out] arraybuffer
:TypedArray
の基になるArrayBuffer
。[out] byte_offset
: 配列の最初の要素が配置されている、基になるネイティブ配列内のバイトオフセット。dataパラメータの値は、dataが配列の最初の要素を指すようにすでに調整されています。したがって、ネイティブ配列の最初のバイトはdata - byte_offset
になります。
APIが成功した場合はnapi_ok
を返します。
このAPIは、型付き配列のさまざまなプロパティを返します。
そのプロパティが不要な場合、出力パラメータのいずれかがNULL
になる可能性があります。
警告: 基になるデータバッファはVMによって管理されるため、この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)
[in] env
: APIが呼び出される環境。[in] dataview
: プロパティをクエリするDataView
を表すnapi_value
。[out] byte_length
:DataView
内のバイト数。[out] data
:DataView
の基になるデータバッファ。byte_lengthが0
の場合、これはNULL
またはその他のポインタ値になる可能性があります。[out] arraybuffer
:DataView
の基になるArrayBuffer
。[out] byte_offset
:DataView
の投影を開始するデータバッファ内のバイトオフセット。
APIが成功した場合はnapi_ok
を返します。
そのプロパティが不要な場合、出力パラメータのいずれかがNULL
になる可能性があります。
このAPIは、DataView
のさまざまなプロパティを返します。
napi_get_date_value
#
napi_status napi_get_date_value(napi_env env,
napi_value value,
double* result)
[in] env
: APIが呼び出される環境。[in] value
: JavaScriptのDate
を表すnapi_value
。[out] result
: 1970年1月1日UTCの午前0時からの経過時間をミリ秒単位で表したdouble
としての時間値。
このAPIはうるう秒を考慮しません。ECMAScriptはPOSIX時間仕様に準拠しているため、無視されます。
APIが成功した場合はnapi_ok
を返します。日付以外のnapi_value
が渡された場合はnapi_date_expected
を返します。
このAPIは、指定されたJavaScriptのDate
の時間値のCのdoubleプリミティブを返します。
napi_get_value_bool
#
napi_status napi_get_value_bool(napi_env env, napi_value value, bool* result)
[in] env
: APIが呼び出される環境。[in] value
: JavaScriptのBoolean
を表すnapi_value
。[out] result
: 指定されたJavaScriptのBoolean
と同等のCのブールプリミティブ。
APIが成功した場合はnapi_ok
を返します。ブール値以外のnapi_value
が渡された場合はnapi_boolean_expected
を返します。
このAPIは、指定されたJavaScriptのBoolean
と同等のCのブールプリミティブを返します。
napi_get_value_double
#
napi_status napi_get_value_double(napi_env env,
napi_value value,
double* result)
[in] env
: APIが呼び出される環境。[in] value
: JavaScript のnumber
を表すnapi_value
。[out] result
: 指定された JavaScript のnumber
に相当する C の double 型プリミティブ。
API が成功した場合は napi_ok
を返します。数値以外の napi_value
が渡された場合は、napi_number_expected
を返します。
この API は、指定された JavaScript の number
に相当する C の double 型プリミティブを返します。
napi_get_value_bigint_int64
#
napi_status napi_get_value_bigint_int64(napi_env env,
napi_value value,
int64_t* result,
bool* lossless);
[in] env
: API が呼び出される環境。[in] value
: JavaScript のBigInt
を表すnapi_value
。[out] result
: 指定された JavaScript のBigInt
に相当する C のint64_t
型プリミティブ。[out] lossless
:BigInt
値が損失なく変換されたかどうかを示します。
API が成功した場合は napi_ok
を返します。BigInt
以外の値が渡された場合は、napi_bigint_expected
を返します。
この API は、指定された JavaScript の BigInt
に相当する C の int64_t
型プリミティブを返します。必要に応じて値を切り捨て、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);
[in] env
: APIが呼び出される環境。[in] value
: JavaScript のBigInt
を表すnapi_value
。[out] result
: 指定された JavaScript のBigInt
に相当する C のuint64_t
型プリミティブ。[out] lossless
:BigInt
値が損失なく変換されたかどうかを示します。
API が成功した場合は napi_ok
を返します。BigInt
以外の値が渡された場合は、napi_bigint_expected
を返します。
この API は、指定された JavaScript の BigInt
に相当する C の uint64_t
型プリミティブを返します。必要に応じて値を切り捨て、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);
[in] env
: APIが呼び出される環境。[in] value
: JavaScript のBigInt
を表すnapi_value
。[out] sign_bit
: JavaScript のBigInt
が正か負かを示す整数。[in/out] word_count
:words
配列の長さに初期化する必要があります。戻り時に、このBigInt
を格納するために必要な実際のワード数が設定されます。[out] words
: 事前に割り当てられた 64 ビットワード配列へのポインタ。
APIが成功した場合はnapi_ok
を返します。
この 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)
[in] env
: APIが呼び出される環境。[in] value
: JavaScript の外部値を表すnapi_value
。[out] result
: JavaScript の外部値によってラップされたデータへのポインタ。
API が成功した場合は napi_ok
を返します。外部値以外の 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)
[in] env
: APIが呼び出される環境。[in] value
: JavaScript のnumber
を表すnapi_value
。[out] result
: 指定された JavaScript のnumber
に相当する C のint32
型プリミティブ。
API が成功した場合は napi_ok
を返します。数値以外の napi_value
が渡された場合は、napi_number_expected
を返します。
この API は、指定された JavaScript の number
に相当する C の int32
型プリミティブを返します。
数値が 32 ビット整数の範囲を超える場合、結果は下位 32 ビットに相当する値に切り捨てられます。値が 231 - 1 を超える場合、大きな正の数が負の数になる可能性があります。
非有限数値 (NaN
, +Infinity
, または -Infinity
) の場合、結果は 0 に設定されます。
napi_get_value_int64
#
napi_status napi_get_value_int64(napi_env env,
napi_value value,
int64_t* result)
[in] env
: APIが呼び出される環境。[in] value
: JavaScript のnumber
を表すnapi_value
。[out] result
: 指定された JavaScript のnumber
に相当する C のint64
型プリミティブ。
API が成功した場合は napi_ok
を返します。数値以外の napi_value
が渡された場合は、napi_number_expected
を返します。
この API は、指定された JavaScript の number
に相当する C の int64
型プリミティブを返します。
Number.MIN_SAFE_INTEGER
-(2**53 - 1)
- Number.MAX_SAFE_INTEGER
(2**53 - 1)
の範囲外の number
値は、精度が失われます。
非有限数値 (NaN
, +Infinity
, または -Infinity
) の場合、結果は 0 に設定されます。
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)
[in] env
: APIが呼び出される環境。[in] value
: JavaScript の文字列を表すnapi_value
。[in] buf
: ISO-8859-1 でエンコードされた文字列を書き込むためのバッファ。NULL
が渡された場合、文字列の長さ (バイト単位、null 終端文字を除く) がresult
で返されます。[in] bufsize
: 宛先バッファのサイズ。この値が不十分な場合、返される文字列は切り詰められ、null で終端されます。[out] result
: バッファにコピーされたバイト数(null 終端文字を除く)。
API が成功した場合は napi_ok
を返します。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)
[in] env
: APIが呼び出される環境。[in] value
: JavaScript の文字列を表すnapi_value
。[in] buf
: UTF8 エンコード文字列を書き込むためのバッファ。NULL
が渡された場合、文字列の長さ (バイト単位、null 終端文字を除く) がresult
で返されます。[in] bufsize
: 宛先バッファのサイズ。この値が不十分な場合、返される文字列は切り詰められ、null で終端されます。[out] result
: バッファにコピーされたバイト数(null 終端文字を除く)。
API が成功した場合は napi_ok
を返します。string
以外の napi_value
が渡された場合は、napi_string_expected
を返します。
この API は、渡された値に対応する UTF8 エンコード文字列を返します。
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)
[in] env
: APIが呼び出される環境。[in] value
: JavaScript の文字列を表すnapi_value
。[in] buf
: UTF16-LE エンコード文字列を書き込むためのバッファ。NULL
が渡された場合、文字列の長さ (2 バイトコード単位、null 終端文字を除く) が返されます。[in] bufsize
: 宛先バッファのサイズ。この値が不十分な場合、返される文字列は切り詰められ、null で終端されます。[out] result
: バッファにコピーされた 2 バイトコード単位の数 (null 終端文字を除く)。
API が成功した場合は napi_ok
を返します。string
以外の napi_value
が渡された場合は、napi_string_expected
を返します。
この API は、渡された値に対応する UTF16 エンコード文字列を返します。
napi_get_value_uint32
#
napi_status napi_get_value_uint32(napi_env env,
napi_value value,
uint32_t* result)
[in] env
: APIが呼び出される環境。[in] value
: JavaScript のnumber
を表すnapi_value
。[out] result
: 指定されたnapi_value
に相当する C プリミティブ (uint32_t
型)。
API が成功した場合は napi_ok
を返します。数値以外の napi_value
が渡された場合は、napi_number_expected
を返します。
この API は、指定された napi_value
に相当する C プリミティブ (uint32_t
型) を返します。
グローバルインスタンスを取得する関数#
napi_get_boolean
#
napi_status napi_get_boolean(napi_env env, bool value, napi_value* result)
[in] env
: APIが呼び出される環境。[in] value
: 取得するブール値。[out] result
: 取得する JavaScript のBoolean
シングルトンを表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
この API は、指定されたブール値を表すために使用される JavaScript シングルトンオブジェクトを返すために使用されます。
napi_get_global
#
napi_status napi_get_global(napi_env env, napi_value* result)
[in] env
: APIが呼び出される環境。[out] result
: JavaScript のglobal
オブジェクトを表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
この API は、global
オブジェクトを返します。
napi_get_null
#
napi_status napi_get_null(napi_env env, napi_value* result)
[in] env
: APIが呼び出される環境。[out] result
: JavaScript のnull
オブジェクトを表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
この API は、null
オブジェクトを返します。
napi_get_undefined
#
napi_status napi_get_undefined(napi_env env, napi_value* result)
[in] env
: APIが呼び出される環境。[out] result
: JavaScript の Undefined 値を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
この API は、Undefined オブジェクトを返します。
JavaScript 値と抽象的な操作の扱い#
Node-API は、JavaScript 値に対していくつかの抽象的な操作を実行するための API セットを公開します。これらの操作の一部は、ECMAScript 言語仕様の 第 7 章 で文書化されています。
これらの API は、次のいずれかの実行をサポートします。
- JavaScript の値を特定の JavaScript 型 (
number
やstring
など) に強制変換します。 - JavaScript 値の型を確認します。
- 2 つの JavaScript 値の等価性を確認します。
napi_coerce_to_bool
#
napi_status napi_coerce_to_bool(napi_env env,
napi_value value,
napi_value* result)
[in] env
: APIが呼び出される環境。[in] value
: 強制変換する JavaScript 値。[out] result
: 強制変換された JavaScript のBoolean
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
この API は、ECMAScript 言語仕様の 第 7.1.2 章 で定義されている抽象的な操作 ToBoolean()
を実装します。
napi_coerce_to_number
#
napi_status napi_coerce_to_number(napi_env env,
napi_value value,
napi_value* result)
[in] env
: APIが呼び出される環境。[in] value
: 強制変換する JavaScript 値。[out] result
: 強制変換された JavaScript のnumber
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
この API は、ECMAScript 言語仕様の 第 7.1.3 章 で定義されている抽象的な操作 ToNumber()
を実装します。この関数は、渡された値がオブジェクトの場合、JS コードを実行する可能性があります。
napi_coerce_to_object
#
napi_status napi_coerce_to_object(napi_env env,
napi_value value,
napi_value* result)
[in] env
: APIが呼び出される環境。[in] value
: 強制変換する JavaScript 値。[out] result
: 強制変換された JavaScript のObject
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
この API は、ECMAScript 言語仕様の 第 7.1.13 章 で定義されている抽象的な操作 ToObject()
を実装します。
napi_coerce_to_string
#
napi_status napi_coerce_to_string(napi_env env,
napi_value value,
napi_value* result)
[in] env
: APIが呼び出される環境。[in] value
: 強制変換する JavaScript 値。[out] result
: 強制変換された JavaScript のstring
を表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
この API は、ECMAScript 言語仕様の 第 7.1.13 章 で定義されている抽象的な操作 ToString()
を実装します。この関数は、渡された値がオブジェクトの場合、JS コードを実行する可能性があります。
napi_typeof
#
napi_status napi_typeof(napi_env env, napi_value value, napi_valuetype* result)
[in] env
: APIが呼び出される環境。[in] value
: 型を照会する JavaScript 値。[out] result
: JavaScript 値の型。
APIが成功した場合はnapi_ok
を返します。
value
の型が既知の ECMAScript 型ではなく、value
が外部値でもない場合は、napi_invalid_arg
が返されます。
この API は、ECMAScript 言語仕様の 第 12.5.5 章 で定義されているオブジェクトに対して typeof
演算子を呼び出すのと同様の動作を表します。ただし、いくつかの違いがあります。
- 外部値の検出をサポートしています。
null
を別の型として検出しますが、ECMAScript のtypeof
はobject
を検出します。
value
に無効な型がある場合、エラーが返されます。
napi_instanceof
#
napi_status napi_instanceof(napi_env env,
napi_value object,
napi_value constructor,
bool* result)
[in] env
: APIが呼び出される環境。[in] object
: チェックする JavaScript 値。[in] constructor
: チェック対象のコンストラクタ関数の JavaScript 関数オブジェクト。[out] result
:object instanceof constructor
が true の場合に true に設定されるブール値。
APIが成功した場合はnapi_ok
を返します。
この API は、ECMAScript 言語仕様の 第 12.10.4 章 で定義されているオブジェクトに対して instanceof
演算子を呼び出すのを表します。
napi_is_array
#
napi_status napi_is_array(napi_env env, napi_value value, bool* result)
[in] env
: APIが呼び出される環境。[in] value
: チェックする JavaScript 値。[out] result
: 指定されたオブジェクトが配列であるかどうか。
APIが成功した場合はnapi_ok
を返します。
この API は、ECMAScript 言語仕様の 第 7.2.2 章 で定義されているオブジェクトに対して IsArray
操作を呼び出すのを表します。
napi_is_arraybuffer
#
napi_status napi_is_arraybuffer(napi_env env, napi_value value, bool* result)
[in] env
: APIが呼び出される環境。[in] value
: チェックする JavaScript 値。[out] result
: 指定されたオブジェクトがArrayBuffer
であるかどうか。
APIが成功した場合はnapi_ok
を返します。
このAPIは、渡されたObject
が配列バッファであるかどうかをチェックします。
napi_is_buffer
#
napi_status napi_is_buffer(napi_env env, napi_value value, bool* result)
[in] env
: APIが呼び出される環境。[in] value
: チェックする JavaScript 値。[out] result
: 指定されたnapi_value
がnode::Buffer
またはUint8Array
オブジェクトを表すかどうか。
APIが成功した場合はnapi_ok
を返します。
このAPIは、渡されたObject
がバッファまたはUint8Arrayであるかどうかをチェックします。値がUint8Arrayであるかどうかをチェックする必要がある場合は、napi_is_typedarray
を優先する必要があります。
napi_is_date
#
napi_status napi_is_date(napi_env env, napi_value value, bool* result)
[in] env
: APIが呼び出される環境。[in] value
: チェックする JavaScript 値。[out] result
: 指定されたnapi_value
がJavaScriptのDate
オブジェクトを表すかどうか。
APIが成功した場合はnapi_ok
を返します。
このAPIは、渡されたObject
が日付であるかどうかをチェックします。
napi_is_error
#
napi_status napi_is_error(napi_env env, napi_value value, bool* result)
[in] env
: APIが呼び出される環境。[in] value
: チェックする JavaScript 値。[out] result
: 指定されたnapi_value
がError
オブジェクトを表すかどうか。
APIが成功した場合はnapi_ok
を返します。
このAPIは、渡されたObject
がError
であるかどうかをチェックします。
napi_is_typedarray
#
napi_status napi_is_typedarray(napi_env env, napi_value value, bool* result)
[in] env
: APIが呼び出される環境。[in] value
: チェックする JavaScript 値。[out] result
: 指定されたnapi_value
がTypedArray
を表すかどうか。
APIが成功した場合はnapi_ok
を返します。
このAPIは、渡されたObject
が型付き配列であるかどうかをチェックします。
napi_is_dataview
#
napi_status napi_is_dataview(napi_env env, napi_value value, bool* result)
[in] env
: APIが呼び出される環境。[in] value
: チェックする JavaScript 値。[out] result
: 指定されたnapi_value
がDataView
を表すかどうか。
APIが成功した場合はnapi_ok
を返します。
このAPIは、渡されたObject
がDataView
であるかどうかをチェックします。
napi_strict_equals
#
napi_status napi_strict_equals(napi_env env,
napi_value lhs,
napi_value rhs,
bool* result)
[in] env
: APIが呼び出される環境。[in] lhs
: チェックするJavaScriptの値。[in] rhs
: チェック対象のJavaScriptの値。[out] result
: 2つのnapi_value
オブジェクトが等しいかどうか。
APIが成功した場合はnapi_ok
を返します。
このAPIは、ECMAScript言語仕様のセクション7.2.14で定義されている厳密等価性アルゴリズムの呼び出しを表します。
napi_detach_arraybuffer
#
napi_status napi_detach_arraybuffer(napi_env env,
napi_value arraybuffer)
[in] env
: APIが呼び出される環境。[in] arraybuffer
: デタッチされるJavaScriptのArrayBuffer
。
APIが成功した場合はnapi_ok
を返します。デタッチ不可能なArrayBuffer
が渡された場合は、napi_detachable_arraybuffer_expected
を返します。
一般的に、ArrayBuffer
は以前にデタッチされている場合はデタッチ不可能です。エンジンは、ArrayBuffer
がデタッチ可能かどうかについて追加の条件を課す場合があります。たとえば、V8では、ArrayBuffer
が外部であること、つまりnapi_create_external_arraybuffer
で作成されている必要があります。
このAPIは、ECMAScript言語仕様のセクション24.1.1.3で定義されているArrayBuffer
のデタッチ操作の呼び出しを表します。
napi_is_detached_arraybuffer
#
napi_status napi_is_detached_arraybuffer(napi_env env,
napi_value arraybuffer,
bool* result)
[in] env
: APIが呼び出される環境。[in] arraybuffer
: チェックするJavaScriptのArrayBuffer
。[out] result
:arraybuffer
がデタッチされているかどうか。
APIが成功した場合はnapi_ok
を返します。
内部データがnull
の場合、ArrayBuffer
はデタッチされていると見なされます。
このAPIは、ECMAScript言語仕様のセクション24.1.1.2で定義されているArrayBuffer
のIsDetachedBuffer
操作の呼び出しを表します。
JavaScriptプロパティの操作#
Node-APIは、JavaScriptオブジェクトのプロパティを取得および設定するための一連のAPIを公開しています。これらの型のいくつかは、セクション7のECMAScript言語仕様に記載されています。
JavaScriptのプロパティは、キーと値のタプルとして表されます。基本的に、Node-APIのすべてのプロパティキーは、次のいずれかの形式で表すことができます。
- 名前付き: 単純なUTF8エンコード文字列
- 整数インデックス:
uint32_t
で表されるインデックス値 - JavaScriptの値: これらはNode-APIでは
napi_value
で表されます。これは、string
、number
、またはsymbol
を表すnapi_value
である可能性があります。
Node-APIの値は、型napi_value
で表されます。JavaScriptの値を必要とするNode-API呼び出しは、napi_value
を受け取ります。ただし、問題のnapi_value
がAPIで想定されているJavaScriptの型であることを確認するのは、呼び出し側の責任です。
このセクションで説明するAPIは、napi_value
で表される任意のJavaScriptオブジェクトのプロパティを取得および設定するための簡単なインターフェースを提供します。
たとえば、次のJavaScriptコードスニペットを考えてみましょう
const obj = {};
obj.myProp = 123;
同様のことは、次のスニペットを使用して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;
インデックス付きプロパティも同様の方法で設定できます。次のJavaScriptスニペットを考えてみましょう
const arr = [];
arr[123] = 'hello';
同様のことは、次のスニペットを使用して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;
プロパティは、このセクションで説明するAPIを使用して取得できます。次のJavaScriptスニペットを考えてみましょう
const arr = [];
const value = arr[123];
以下は、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;
最後に、パフォーマンス上の理由から、オブジェクトに複数のプロパティを定義することもできます。次のJavaScriptを考えてみましょう
const obj = {};
Object.defineProperties(obj, {
'foo': { value: 123, writable: true, configurable: true, enumerable: true },
'bar': { value: 456, writable: true, configurable: true, enumerable: true },
});
以下は、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;
構造体#
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;
napi_property_attributes
は、JavaScriptオブジェクトに設定されたプロパティの動作を制御するために使用されるフラグです。napi_static
以外は、セクション6.1.7.1のECMAScript言語仕様にリストされている属性に対応します。これらは、次の1つ以上のビットフラグにすることができます。
napi_default
: プロパティに明示的な属性は設定されていません。デフォルトでは、プロパティは読み取り専用で、列挙可能ではなく、構成可能ではありません。napi_writable
: プロパティは書き込み可能です。napi_enumerable
: プロパティは列挙可能です。napi_configurable
: プロパティは、セクション6.1.7.1の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;
utf8name
: プロパティのキーを記述するオプションの文字列(UTF8エンコード)。プロパティには、utf8name
またはname
のいずれかを指定する必要があります。name
: プロパティのキーとして使用されるJavaScript文字列またはシンボルを指すオプションのnapi_value
。プロパティには、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
プロパティがmethod
で表されるJavaScript関数になるようにします。これを渡す場合は、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);
[in] env
: Node-API呼び出しが実行される環境。[in] object
: プロパティを取得するオブジェクト。[out] result
: オブジェクトのプロパティ名を表現するJavaScript値の配列を表すnapi_value
。APIを使用して、napi_get_array_length
およびnapi_get_element
を使用してresult
を反復処理できます。
APIが成功した場合はnapi_ok
を返します。
この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);
[in] env
: Node-API呼び出しが実行される環境。[in] object
: プロパティを取得するオブジェクト。[in] key_mode
: プロトタイププロパティも取得するかどうか。[in] key_filter
: 取得するプロパティ(列挙可能/読み取り可能/書き込み可能)。[in] key_conversion
: 番号付きプロパティキーを文字列に変換するかどうか。[out] result
: オブジェクトのプロパティ名を表現するJavaScript値の配列を表すnapi_value
。napi_get_array_length
およびnapi_get_element
を使用してresult
を反復処理できます。
APIが成功した場合はnapi_ok
を返します。
このAPIは、このオブジェクトの使用可能なプロパティの名前を含む配列を返します。
napi_set_property
#
napi_status napi_set_property(napi_env env,
napi_value object,
napi_value key,
napi_value value);
[in] env
: Node-API呼び出しが実行される環境。[in] object
: プロパティを設定するオブジェクト。[in] key
: 設定するプロパティの名前。[in] value
: プロパティの値。
APIが成功した場合はnapi_ok
を返します。
このAPIは、渡されたObject
にプロパティを設定します。
napi_get_property
#
napi_status napi_get_property(napi_env env,
napi_value object,
napi_value key,
napi_value* result);
[in] env
: Node-API呼び出しが実行される環境。[in] object
: プロパティを取得するオブジェクト。[in] key
: 取得するプロパティの名前。[out] result
: プロパティの値。
APIが成功した場合はnapi_ok
を返します。
このAPIは、渡されたObject
から要求されたプロパティを取得します。
napi_has_property
#
napi_status napi_has_property(napi_env env,
napi_value object,
napi_value key,
bool* result);
[in] env
: Node-API呼び出しが実行される環境。[in] object
: クエリを実行するオブジェクト。[in] key
: 存在を確認するプロパティの名前。[out] result
: プロパティがオブジェクトに存在するかどうか。
APIが成功した場合はnapi_ok
を返します。
このAPIは、渡されたObject
に指定された名前のプロパティがあるかどうかをチェックします。
napi_delete_property
#
napi_status napi_delete_property(napi_env env,
napi_value object,
napi_value key,
bool* result);
[in] env
: Node-API呼び出しが実行される環境。[in] object
: クエリを実行するオブジェクト。[in] key
: 削除するプロパティの名前。[out] result
: プロパティの削除が成功したかどうか。result
は、NULL
を渡すことでオプションで無視できます。
APIが成功した場合はnapi_ok
を返します。
このAPIは、object
からkey
自身のプロパティを削除しようとします。
napi_has_own_property
#
napi_status napi_has_own_property(napi_env env,
napi_value object,
napi_value key,
bool* result);
[in] env
: Node-API呼び出しが実行される環境。[in] object
: クエリを実行するオブジェクト。[in] key
: チェックする自身のプロパティの名前。[out] result
: オブジェクトに自身のプロパティが存在するかどうか。
APIが成功した場合はnapi_ok
を返します。
この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);
[in] env
: Node-API呼び出しが実行される環境。[in] object
: プロパティを設定するオブジェクト。[in] utf8Name
: 設定するプロパティの名前。[in] value
: プロパティの値。
APIが成功した場合はnapi_ok
を返します。
このメソッドは、utf8Name
として渡された文字列から作成されたnapi_value
でnapi_set_property
を呼び出すことと同等です。
napi_get_named_property
#
napi_status napi_get_named_property(napi_env env,
napi_value object,
const char* utf8Name,
napi_value* result);
[in] env
: Node-API呼び出しが実行される環境。[in] object
: プロパティを取得するオブジェクト。[in] utf8Name
: 取得するプロパティの名前。[out] result
: プロパティの値。
APIが成功した場合はnapi_ok
を返します。
このメソッドは、utf8Name
として渡された文字列から作成されたnapi_value
でnapi_get_property
を呼び出すことと同等です。
napi_has_named_property
#
napi_status napi_has_named_property(napi_env env,
napi_value object,
const char* utf8Name,
bool* result);
[in] env
: Node-API呼び出しが実行される環境。[in] object
: クエリを実行するオブジェクト。[in] utf8Name
: 存在を確認するプロパティの名前。[out] result
: プロパティがオブジェクトに存在するかどうか。
APIが成功した場合はnapi_ok
を返します。
このメソッドは、utf8Name
として渡された文字列から作成されたnapi_value
でnapi_has_property
を呼び出すことと同等です。
napi_set_element
#
napi_status napi_set_element(napi_env env,
napi_value object,
uint32_t index,
napi_value value);
[in] env
: Node-API呼び出しが実行される環境。[in] object
: プロパティを設定するオブジェクト。[in] index
: 設定するプロパティのインデックス。[in] value
: プロパティの値。
APIが成功した場合はnapi_ok
を返します。
このAPIは、渡されたObject
の要素を設定します。
napi_get_element
#
napi_status napi_get_element(napi_env env,
napi_value object,
uint32_t index,
napi_value* result);
[in] env
: Node-API呼び出しが実行される環境。[in] object
: プロパティを取得するオブジェクト。[in] index
: 取得するプロパティのインデックス。[out] result
: プロパティの値。
APIが成功した場合はnapi_ok
を返します。
このAPIは、要求されたインデックスの要素を取得します。
napi_has_element
#
napi_status napi_has_element(napi_env env,
napi_value object,
uint32_t index,
bool* result);
[in] env
: Node-API呼び出しが実行される環境。[in] object
: クエリを実行するオブジェクト。[in] index
: 存在を確認するプロパティのインデックス。[out] result
: プロパティがオブジェクトに存在するかどうか。
APIが成功した場合はnapi_ok
を返します。
このAPIは、渡されたObject
が要求されたインデックスに要素を持っているかどうかを返します。
napi_delete_element
#
napi_status napi_delete_element(napi_env env,
napi_value object,
uint32_t index,
bool* result);
[in] env
: Node-API呼び出しが実行される環境。[in] object
: クエリを実行するオブジェクト。[in] index
: 削除するプロパティのインデックス。[out] result
: 要素の削除が成功したかどうか。result
は、NULL
を渡すことでオプションで無視できます。
APIが成功した場合はnapi_ok
を返します。
このAPIは、object
から指定されたindex
を削除しようとします。
napi_define_properties
#
napi_status napi_define_properties(napi_env env,
napi_value object,
size_t property_count,
const napi_property_descriptor* properties);
[in] env
: Node-API呼び出しが実行される環境。[in] object
: プロパティを取得するオブジェクト。[in] property_count
:properties
配列内の要素数。[in] properties
: プロパティ記述子の配列。
APIが成功した場合はnapi_ok
を返します。
このメソッドは、指定されたオブジェクトに複数のプロパティを効率的に定義できるようにします。プロパティはプロパティ記述子(napi_property_descriptor
を参照)を使用して定義されます。このようなプロパティ記述子の配列が与えられた場合、このAPIは、DefineOwnProperty()
(ECMA-262仕様のセクション9.1.6で説明)で定義されているように、一度に1つずつオブジェクトにプロパティを設定します。
napi_object_freeze
#
napi_status napi_object_freeze(napi_env env,
napi_value object);
[in] env
: Node-API呼び出しが実行される環境。[in] object
: フリーズするオブジェクト。
APIが成功した場合はnapi_ok
を返します。
このメソッドは、与えられたオブジェクトをフリーズします。これにより、新しいプロパティが追加されるのを防ぎ、既存のプロパティが削除されるのを防ぎ、既存のプロパティの列挙可能性、構成可能性、または書き込み可能性を変更するのを防ぎ、既存のプロパティの値が変更されるのを防ぎます。また、オブジェクトのプロトタイプが変更されるのも防ぎます。これは、ECMA-262仕様のセクション19.1.2.6で説明されています。
napi_object_seal
#
napi_status napi_object_seal(napi_env env,
napi_value object);
[in] env
: Node-API呼び出しが実行される環境。[in] object
: シールするオブジェクト。
APIが成功した場合はnapi_ok
を返します。
このメソッドは、与えられたオブジェクトをシールします。これにより、新しいプロパティが追加されるのを防ぎ、既存のすべてのプロパティを構成不可としてマークします。これは、ECMA-262仕様のセクション19.1.2.20で説明されています。
JavaScript関数を操作する#
Node-APIは、JavaScriptコードがネイティブコードにコールバックできるようにするAPIのセットを提供します。ネイティブコードへのコールバックをサポートするNode-APIは、napi_callback
型で表されるコールバック関数を受け入れます。JavaScript VMがネイティブコードにコールバックすると、提供されたnapi_callback
関数が呼び出されます。このセクションで説明するAPIを使用すると、コールバック関数は次のことができます。
- コールバックが呼び出されたコンテキストに関する情報を取得します。
- コールバックに渡された引数を取得します。
- コールバックから
napi_value
を返します。
さらに、Node-APIは、ネイティブコードからJavaScript関数を呼び出すことができる一連の関数を提供します。関数を通常のJavaScript関数呼び出しのように呼び出すことも、コンストラクター関数として呼び出すこともできます。
napi_property_descriptor
項目のdata
フィールドを介してこのAPIに渡される非NULL
データは、object
に関連付けることができ、object
とデータをnapi_add_finalizer
に渡すことによって、object
がガベージコレクションされるたびに解放できます。
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);
[in] env
: APIが呼び出される環境。[in] recv
: 呼び出される関数に渡されるthis
値。[in] func
: 呼び出すJavaScript関数を表すnapi_value
。[in] argc
:argv
配列内の要素数。[in] argv
: 関数への引数として渡されるJavaScript値を表すnapi_value
の配列。[out] result
: 返されたJavaScriptオブジェクトを表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
このメソッドを使用すると、JavaScript関数オブジェクトをネイティブアドオンから呼び出すことができます。これは、アドオンのネイティブコードからJavaScriptにコールバックする主要なメカニズムです。非同期操作後にJavaScriptを呼び出す特殊なケースについては、napi_make_callback
を参照してください。
サンプル使用例は次のようになります。次のJavaScriptスニペットを考えてみましょう。
function AddTwo(num) {
return num + 2;
}
global.AddTwo = AddTwo;
次に、上記関数は、次のコードを使用してネイティブアドオンから呼び出すことができます。
// 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;
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);
[in] env
: APIが呼び出される環境。[in] utf8Name
: UTF8としてエンコードされた関数のオプションの名前。これは、新しい関数オブジェクトのname
プロパティとしてJavaScript内で表示されます。[in] length
: バイト単位のutf8name
の長さ。null終端の場合はNAPI_AUTO_LENGTH
。[in] cb
: この関数オブジェクトが呼び出されたときに呼び出す必要があるネイティブ関数。napi_callback
は詳細を提供します。[in] data
: ユーザー提供のデータコンテキスト。これは、後で呼び出されたときに関数に渡されます。[out] result
: 新しく作成された関数のJavaScript関数オブジェクトを表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
このAPIを使用すると、アドオン作成者はネイティブコードで関数オブジェクトを作成できます。これは、JavaScriptからアドオンのネイティブコードに呼び出すための主要なメカニズムです。
新しく作成された関数は、この呼び出し後、スクリプトから自動的に表示されるわけではありません。代わりに、スクリプトから関数にアクセスできるようにするために、JavaScriptに表示される任意のオブジェクトにプロパティを明示的に設定する必要があります。
アドオンのモジュールエクスポートの一部として関数を公開するには、エクスポートオブジェクトに新しく作成された関数を設定します。サンプルモジュールは次のようになります。
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)
上記のコードが与えられた場合、アドオンはJavaScriptから次のように使用できます。
const myaddon = require('./addon');
myaddon.sayHello();
require()
に渡される文字列は、.node
ファイルの作成を担当するbinding.gyp
内のターゲットの名前です。
data
パラメーターを介してこのAPIに渡される非NULL
データは、結果のJavaScript関数(result
パラメーターで返されます)に関連付けることができ、JavaScript関数とデータをnapi_add_finalizer
に渡すことによって、関数がガベージコレクションされるたびに解放できます。
JavaScriptのFunction
については、ECMAScript言語仕様のセクション19.2で説明されています。
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)
[in] env
: APIが呼び出される環境。[in] cbinfo
: コールバック関数に渡されたコールバック情報。[in-out] argc
: 提供されたargv
配列の長さを指定し、実際の引数の数を取得します。argc
は、NULL
を渡すことでオプションで無視できます。[out] argv
: 引数がコピーされるnapi_value
のC配列。提供された数よりも多くの引数がある場合は、要求された数の引数のみがコピーされます。主張された数よりも少ない引数が提供された場合、残りのargv
はundefined
を表すnapi_value
値で埋められます。argv
は、NULL
を渡すことでオプションで無視できます。[out] thisArg
: 呼び出しのJavaScriptthis
引数を受け取ります。thisArg
は、NULL
を渡すことでオプションで無視できます。[out] data
: コールバックのデータポインターを受け取ります。data
は、NULL
を渡すことでオプションで無視できます。
APIが成功した場合はnapi_ok
を返します。
このメソッドは、指定されたコールバック情報から引数やthis
ポインターのような呼び出しに関する詳細を取得するために、コールバック関数内で使用されます。
napi_get_new_target
#
napi_status napi_get_new_target(napi_env env,
napi_callback_info cbinfo,
napi_value* result)
[in] env
: APIが呼び出される環境。[in] cbinfo
: コールバック関数に渡されたコールバック情報。[out] result
: コンストラクター呼び出しのnew.target
。
APIが成功した場合はnapi_ok
を返します。
この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)
[in] env
: APIが呼び出される環境。[in] cons
: コンストラクターとして呼び出される JavaScript 関数を表すnapi_value
。[in] argc
:argv
配列内の要素数。[in] argv
: コンストラクターへの引数を表すnapi_value
としての JavaScript 値の配列。argc
がゼロの場合、このパラメーターはNULL
を渡すことで省略できます。[out] result
: 返される JavaScript オブジェクトを表すnapi_value
。この場合は構築されたオブジェクトです。
このメソッドは、オブジェクトのコンストラクターを表す指定された napi_value
を使用して、新しい JavaScript 値をインスタンス化するために使用されます。たとえば、次のスニペットを考えてみてください。
function MyObject(param) {
this.param = param;
}
const arg = 'hello';
const value = new MyObject(arg);
次を 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);
APIが成功した場合はnapi_ok
を返します。
オブジェクトのラップ#
Node-API は、C++ クラスとインスタンスを「ラップ」し、クラスのコンストラクターとメソッドを JavaScript から呼び出せるようにする方法を提供します。
napi_define_class
API は、C++ クラスに対応するコンストラクター、静的プロパティとメソッド、インスタンスプロパティとメソッドを持つ JavaScript クラスを定義します。- JavaScript コードがコンストラクターを呼び出すと、コンストラクターのコールバックは
napi_wrap
を使用して、新しい C++ インスタンスを JavaScript オブジェクトでラップし、ラッパーオブジェクトを返します。 - JavaScript コードがクラスのメソッドまたはプロパティアクセサーを呼び出すと、対応する
napi_callback
C++ 関数が呼び出されます。インスタンスコールバックの場合、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...
}
参照は、不要になったら解放する必要があります。
JavaScript オブジェクトが特定のネイティブ型のラッパーであることを確認するために napi_instanceof()
では不十分な場合があります。これは、ラップされた 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
}
上記の例では、myAddon.queryHasRecords()
は 2 つの引数を受け入れるメソッドです。1 つ目はデータベースハンドル、2 つ目はクエリハンドルです。内部的には、最初引数をアンラップし、結果のポインターをネイティブデータベースハンドルにキャストします。次に、2 番目の引数をアンラップし、結果のポインターをクエリハンドルにキャストします。引数が間違った順序で渡された場合、キャストは機能しますが、基礎となるデータベース操作が失敗するか、無効なメモリアクセスが発生する可能性が高くなります。
最初の引数から取得したポインターが実際にデータベースハンドルへのポインターであり、同様に、2 番目の引数から取得したポインターが実際にクエリハンドルへのポインターであることを保証するために、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;
}
}
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);
[in] env
: APIが呼び出される環境。[in] utf8name
: JavaScript コンストラクター関数の名前。わかりやすくするために、C++ クラスをラップするときは C++ クラス名を使用することをお勧めします。[in] length
: バイト単位のutf8name
の長さ。null終端の場合は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
。
APIが成功した場合はnapi_ok
を返します。
以下を含む JavaScript クラスを定義します。
- クラス名を持つ JavaScript コンストラクター関数。対応する C++ クラスをラップする場合、
constructor
を介して渡されるコールバックを使用して、新しい C++ クラスインスタンスをインスタンス化できます。その後、napi_wrap
を使用して構築中の JavaScript オブジェクトインスタンス内に配置できます。 - 実装が C++ クラスの対応する静的データプロパティ、アクセサー、およびメソッドを呼び出すことができるコンストラクター関数のプロパティ (
napi_static
属性を持つプロパティ記述子によって定義)。 - コンストラクター関数の
prototype
オブジェクトのプロパティ。C++ クラスをラップする場合、C++ クラスの非静的データプロパティ、アクセサー、およびメソッドは、napi_unwrap
を使用して JavaScript オブジェクトインスタンス内に配置された C++ クラスインスタンスを取得した後、napi_static
属性のないプロパティ記述子で指定された静的関数から呼び出すことができます。
C++ クラスをラップする場合、constructor
を介して渡される C++ コンストラクターコールバックは、実際のクラスコンストラクターを呼び出し、新しい C++ インスタンスを JavaScript オブジェクトでラップし、ラッパーオブジェクトを返すクラスの静的メソッドである必要があります。詳細については、napi_wrap
を参照してください。
napi_define_class
から返される JavaScript コンストラクター関数は、多くの場合、後でネイティブコードからクラスの新しいインスタンスを構築したり、提供された値がクラスのインスタンスであるかどうかを確認したりするために保存および使用されます。その場合、関数値がガベージコレクションされるのを防ぐために、napi_create_reference
を使用して、関数値への強力な永続的参照を作成できます。これにより、参照カウントが >= 1 に維持されます。
data
パラメーターを介して、または napi_property_descriptor
配列項目の data
フィールドを介して、この API に渡される非 NULL
データは、結果の 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);
[in] env
: APIが呼び出される環境。[in] js_object
: ネイティブオブジェクトのラッパーになる JavaScript オブジェクト。[in] native_object
: JavaScript オブジェクトでラップされるネイティブインスタンス。[in] finalize_cb
: JavaScript オブジェクトがガベージコレクションされたときにネイティブインスタンスを解放するために使用できるオプションのネイティブコールバック。napi_finalize
に詳細が記載されています。[in] finalize_hint
: ファイナライズコールバックに渡されるオプションのコンテキストヒント。[out] result
: ラップされたオブジェクトへのオプションの参照。
APIが成功した場合はnapi_ok
を返します。
JavaScript オブジェクトでネイティブインスタンスをラップします。ネイティブインスタンスは、後で napi_unwrap()
を使用して取得できます。
JavaScript コードが napi_define_class()
を使用して定義されたクラスのコンストラクターを呼び出すと、コンストラクターの napi_callback
が呼び出されます。ネイティブクラスのインスタンスを構築した後、コールバックは napi_wrap()
を呼び出して、コンストラクターコールバックへの this
引数である既に作成された JavaScript オブジェクトに、新しく構築されたインスタンスをラップする必要があります。(その this
オブジェクトはコンストラクター関数の prototype
から作成されたため、すでにすべてのインスタンスプロパティとメソッドの定義があります。)
通常、クラスインスタンスをラップする場合、ファイナライズコールバックは、ファイナライズコールバックへの data
引数として受信されるネイティブインスタンスを単に削除する必要があります。
オプションで返される参照は、最初は弱参照です。つまり、参照カウントは 0 です。通常、この参照カウントは、インスタンスを有効なままにする必要がある非同期操作中に一時的にインクリメントされます。
注意: オプションで返される参照 (取得した場合) は、ファイナライズコールバックの呼び出しに応答してのみ napi_delete_reference
を介して削除する必要があります。それよりも前に削除すると、ファイナライズコールバックが呼び出されない可能性があります。したがって、参照を取得する場合は、参照を正しく破棄できるようにするためにファイナライズコールバックも必要です。
ファイナライザーコールバックは延期される可能性があり、オブジェクトがガベージコレクションされ (弱参照が無効になり)、ファイナライザーがまだ呼び出されていないウィンドウが残ります。napi_wrap()
によって返される弱参照で napi_get_reference_value()
を使用する場合でも、空の結果を処理する必要があります。
オブジェクトで napi_wrap()
を 2 回目に呼び出すと、エラーが返されます。別のネイティブインスタンスをオブジェクトに関連付けるには、最初に napi_remove_wrap()
を使用します。
napi_unwrap
#
napi_status napi_unwrap(napi_env env,
napi_value js_object,
void** result);
[in] env
: APIが呼び出される環境。[in] js_object
: ネイティブインスタンスに関連付けられたオブジェクト。[out] result
: ラップされたネイティブインスタンスへのポインター。
APIが成功した場合はnapi_ok
を返します。
napi_wrap()
を使用して、JavaScript オブジェクトで以前にラップされたネイティブインスタンスを取得します。
JavaScript コードがクラスのメソッドまたはプロパティアクセサーを呼び出すと、対応する napi_callback
が呼び出されます。コールバックがインスタンスメソッドまたはアクセサー用である場合、コールバックへの this
引数はラッパーオブジェクトです。呼び出しのターゲットであるラップされた C++ インスタンスは、ラッパーオブジェクトで napi_unwrap()
を呼び出すことによって取得できます。
napi_remove_wrap
#
napi_status napi_remove_wrap(napi_env env,
napi_value js_object,
void** result);
[in] env
: APIが呼び出される環境。[in] js_object
: ネイティブインスタンスに関連付けられたオブジェクト。[out] result
: ラップされたネイティブインスタンスへのポインター。
APIが成功した場合はnapi_ok
を返します。
napi_wrap()
を使用して JavaScript オブジェクト js_object
に以前ラップされていたネイティブインスタンスを取得し、ラッピングを解除します。ファイナライズコールバックがラッピングに関連付けられている場合、JavaScript オブジェクトがガベージコレクションされたときに、そのコールバックは呼び出されなくなります。
napi_type_tag_object
#
napi_status napi_type_tag_object(napi_env env,
napi_value js_object,
const napi_type_tag* type_tag);
[in] env
: APIが呼び出される環境。[in] js_object
: マークされる JavaScript オブジェクトまたは外部オブジェクト。[in] type_tag
: オブジェクトにマークされるタグ。
APIが成功した場合はnapi_ok
を返します。
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);
[in] env
: APIが呼び出される環境。[in] js_object
: 型タグを調べる JavaScript オブジェクトまたは外部オブジェクト。[in] type_tag
: オブジェクトで見つかったタグと比較するタグ。[out] result
: 指定された型タグがオブジェクトの型タグと一致するかどうか。オブジェクトに型タグが見つからなかった場合もfalse
が返されます。
APIが成功した場合はnapi_ok
を返します。
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_nogc_finalize finalize_cb,
void* finalize_hint,
napi_ref* result);
[in] env
: APIが呼び出される環境。[in] js_object
: ネイティブデータがアタッチされる JavaScript オブジェクト。[in] finalize_data
:finalize_cb
に渡されるオプションのデータ。[in] finalize_cb
: JavaScript オブジェクトがガベージコレクションされたときにネイティブデータを解放するために使用されるネイティブコールバック。napi_finalize
で詳細が説明されています。[in] finalize_hint
: ファイナライズコールバックに渡されるオプションのコンテキストヒント。[out] result
: JavaScript オブジェクトへのオプションの参照。
APIが成功した場合はnapi_ok
を返します。
js_object
の JavaScript オブジェクトがガベージコレクションされたときに呼び出される napi_finalize
コールバックを追加します。
この API は、1 つの JavaScript オブジェクトに対して複数回呼び出すことができます。
注意: オプションで返される参照 (取得した場合) は、ファイナライズコールバックの呼び出しに応答してのみ napi_delete_reference
を介して削除する必要があります。それよりも前に削除すると、ファイナライズコールバックが呼び出されない可能性があります。したがって、参照を取得する場合は、参照を正しく破棄できるようにするためにファイナライズコールバックも必要です。
node_api_post_finalizer
#
napi_status node_api_post_finalizer(node_api_nogc_env env,
napi_finalize finalize_cb,
void* finalize_data,
void* finalize_hint);
[in] env
: APIが呼び出される環境。[in] finalize_cb
: JavaScript オブジェクトがガベージコレクションされたときにネイティブデータを解放するために使用されるネイティブコールバック。napi_finalize
で詳細が説明されています。[in] finalize_data
:finalize_cb
に渡されるオプションのデータ。[in] finalize_hint
: ファイナライズコールバックに渡されるオプションのコンテキストヒント。
APIが成功した場合はnapi_ok
を返します。
イベントループで非同期的に呼び出されるように napi_finalize
コールバックをスケジュールします。
通常、ファイナライザーは GC(ガベージコレクター)がオブジェクトを収集している間に呼び出されます。その時点で、GC 状態の変更を引き起こす可能性のある Node-API を呼び出すことは無効になり、Node.js がクラッシュします。
node_api_post_finalizer
は、アドオンが GC ファイナライズ以外の時点に、このような Node-API の呼び出しを延期できるようにすることで、この制限を回避するのに役立ちます。
単純な非同期操作#
アドオンモジュールは、実装の一部として libuv から非同期ヘルパーを活用する必要があることがよくあります。これにより、作業の完了前にメソッドが返せるように、非同期的に実行される作業をスケジュールできます。これにより、Node.js アプリケーション全体の実行をブロックすることを回避できます。
Node-API は、最も一般的な非同期ユースケースをカバーする、これらのサポート関数用の ABI 安定インターフェースを提供します。
Node-API は、非同期ワーカーを管理するために使用される napi_async_work
構造を定義します。インスタンスは、napi_create_async_work
および napi_delete_async_work
で作成/削除されます。
execute
コールバックと complete
コールバックは、それぞれエグゼキューターが実行の準備ができたときと、タスクが完了したときに呼び出される関数です。
execute
関数は、JavaScript の実行または JavaScript オブジェクトとの対話につながる可能性のある Node-API の呼び出しを避ける必要があります。ほとんどの場合、Node-API の呼び出しを行う必要のあるコードは、代わりに complete
コールバックで行う必要があります。JavaScript を実行する可能性が高いため、execute コールバックで napi_env
パラメータを使用することは避けてください。
これらの関数は、次のインターフェースを実装します。
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);
これらのメソッドが呼び出されると、渡される data
パラメータは、アドオンが提供する void*
データとなり、napi_create_async_work
呼び出しに渡されます。
作成したら、napi_queue_async_work
関数を使用して、非同期ワーカーを実行待ちにすることができます。
napi_status napi_queue_async_work(node_api_nogc_env env,
napi_async_work work);
作業が実行を開始する前にキャンセルする必要がある場合は、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);
[in] env
: APIが呼び出される環境。[in] async_resource
:async_hooks
のinit
フックに渡される可能性のある、非同期作業に関連付けられたオプションのオブジェクト。[in] async_resource_name
:async_hooks
API によって公開される診断情報に提供されるリソースの種類を識別する識別子。[in] execute
: ロジックを非同期的に実行するために呼び出す必要のあるネイティブ関数。指定された関数はワーカープールのスレッドから呼び出され、メインイベントループスレッドと並行して実行できます。[in] complete
: 非同期ロジックが完了またはキャンセルされたときに呼び出されるネイティブ関数。指定された関数は、メインイベントループスレッドから呼び出されます。napi_async_complete_callback
で詳細が説明されています。[in] data
: ユーザーが提供するデータコンテキスト。これは execute 関数と complete 関数に返されます。[out] result
: 新しく作成された非同期作業へのハンドルであるnapi_async_work*
。
APIが成功した場合はnapi_ok
を返します。
この API は、ロジックを非同期的に実行するために使用される作業オブジェクトを割り当てます。作業が不要になったら、napi_delete_async_work
を使用して解放する必要があります。
async_resource_name
は、null で終わる UTF-8 エンコードされた文字列である必要があります。
async_resource_name
識別子はユーザーによって提供され、実行されている非同期作業の種類を表す必要があります。モジュール名を含めるなど、名前空間を識別子に適用することもお勧めします。詳細については、async_hooks
ドキュメントを参照してください。
napi_delete_async_work
#
napi_status napi_delete_async_work(napi_env env,
napi_async_work work);
[in] env
: APIが呼び出される環境。[in] work
:napi_create_async_work
の呼び出しによって返されたハンドル。
APIが成功した場合はnapi_ok
を返します。
この API は、以前に割り当てられた作業オブジェクトを解放します。
このAPIは、保留中のJavaScript例外がある場合でも呼び出すことができます。
napi_queue_async_work
#
napi_status napi_queue_async_work(node_api_nogc_env env,
napi_async_work work);
[in] env
: APIが呼び出される環境。[in] work
:napi_create_async_work
の呼び出しによって返されたハンドル。
APIが成功した場合はnapi_ok
を返します。
この API は、以前に割り当てられた作業を実行のためにスケジュールすることを要求します。正常に返されたら、この API を同じ napi_async_work
アイテムで再度呼び出してはなりません。そうしないと、結果は未定義になります。
napi_cancel_async_work
#
napi_status napi_cancel_async_work(node_api_nogc_env env,
napi_async_work work);
[in] env
: APIが呼び出される環境。[in] work
:napi_create_async_work
の呼び出しによって返されたハンドル。
APIが成功した場合はnapi_ok
を返します。
この 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)
[in] env
: APIが呼び出される環境。[in] async_resource
:async_hooks
のinit
フックに渡される可能性があり、async_hooks.executionAsyncResource()
でアクセスできる非同期作業に関連付けられたオブジェクト。[in] async_resource_name
:async_hooks
API によって公開される診断情報に提供されるリソースの種類を識別する識別子。[out] result
: 初期化された非同期コンテキスト。
APIが成功した場合はnapi_ok
を返します。
async_hooks
関連の API が正しく動作するように、async_resource
オブジェクトは napi_async_destroy
まで保持する必要があります。以前のバージョンとの ABI 互換性を維持するために、napi_async_context
はメモリリークの原因となることを避けるために、async_resource
オブジェクトへの強い参照を維持していません。ただし、async_resource
が napi_async_destroy
によって破棄される前に JavaScript エンジンによってガベージコレクションされた場合、napi_open_callback_scope
や napi_make_callback
のような napi_async_context
関連の API を呼び出すと、AsyncLocalStorage
API を使用しているときに非同期コンテキストが失われるなどの問題が発生する可能性があります。
以前のバージョンとの ABI 互換性を維持するために、async_resource
に NULL
を渡してもエラーにはなりません。ただし、これは、async_hooks
の init
フックおよび async_hooks.executionAsyncResource()
で望ましくない動作が発生するため、お勧めしません。これは、非同期コールバック間のリンクを提供するために、基盤となる async_hooks
実装によってリソースが必要になったためです。
napi_async_destroy
#
napi_status napi_async_destroy(napi_env env,
napi_async_context async_context);
[in] env
: APIが呼び出される環境。[in] async_context
: 破棄される非同期コンテキスト。
APIが成功した場合はnapi_ok
を返します。
この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);
[in] env
: APIが呼び出される環境。[in] async_context
: コールバックを呼び出している非同期操作のコンテキスト。これは通常、napi_async_init
から以前に取得した値である必要があります。以前のバージョンとの ABI 互換性を維持するために、async_context
にNULL
を渡してもエラーにはなりません。ただし、これは非同期フックの誤った動作を引き起こします。潜在的な問題には、AsyncLocalStorage
API を使用しているときに非同期コンテキストが失われることがあります。[in] recv
: 呼び出される関数に渡されるthis
値。[in] func
: 呼び出すJavaScript関数を表すnapi_value
。[in] argc
:argv
配列内の要素数。[in] argv
: 関数への引数を表すnapi_value
としての JavaScript 値の配列。argc
がゼロの場合、このパラメータはNULL
を渡すことで省略できます。[out] result
: 返されたJavaScriptオブジェクトを表すnapi_value
。
APIが成功した場合はnapi_ok
を返します。
このメソッドを使うと、ネイティブアドオンからJavaScript関数オブジェクトを呼び出すことができます。このAPIは、napi_call_function
に似ています。ただし、非同期操作から戻った後(スタックに他のスクリプトがない場合)に、ネイティブコードから JavaScript へコールバックするために使用されます。これは、node::MakeCallback
の非常にシンプルなラッパーです。
napi_async_complete_callback
内でnapi_make_callback
を使用する必要はないことに注意してください。その状況では、コールバックの非同期コンテキストはすでに設定されているため、napi_call_function
を直接呼び出すだけで十分であり、適切です。 napi_create_async_work
を使用しないカスタムの非同期動作を実装する場合、napi_make_callback
関数が必要になる場合があります。
コールバック中にJavaScriptによってマイクロタスクキューにスケジュールされたprocess.nextTick
やPromiseは、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)
[in] env
: APIが呼び出される環境。[in] resource_object
: 非同期処理に関連付けられたオブジェクト。async_hooks
のinit
フックに渡されます。このパラメータは非推奨となり、実行時には無視されます。代わりにnapi_async_init
のasync_resource
パラメータを使用してください。[in] context
: コールバックを呼び出している非同期操作のコンテキスト。これは、以前にnapi_async_init
から取得した値である必要があります。[out] result
: 新しく作成されたスコープ。
特定のNode-API呼び出しを行う際に、コールバックに関連付けられたスコープと同等のものが必要な場合があります(例:Promiseを解決する場合)。スタックに他のスクリプトがない場合は、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)
[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_nogc_env env,
const napi_node_version** version);
[in] env
: APIが呼び出される環境。[out] version
: 実行中のNode.js自体のバージョン情報へのポインタ。
APIが成功した場合はnapi_ok
を返します。
この関数は、現在実行中のNode.jsのメジャー、マイナー、パッチバージョンをversion
構造体に格納し、release
フィールドにprocess.release.name
の値を格納します。
返されるバッファは静的に割り当てられており、解放する必要はありません。
napi_get_version
#
napi_status napi_get_version(node_api_nogc_env env,
uint32_t* result);
[in] env
: APIが呼び出される環境。[out] result
: サポートされているNode-APIの最高バージョン。
APIが成功した場合はnapi_ok
を返します。
このAPIは、Node.jsランタイムでサポートされているNode-APIの最高バージョンを返します。 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_nogc_env env,
int64_t change_in_bytes,
int64_t* result);
[in] env
: APIが呼び出される環境。[in] change_in_bytes
: JavaScriptオブジェクトによって保持される外部で割り当てられたメモリの変更量。[out] result
: 調整された値
APIが成功した場合はnapi_ok
を返します。
この関数は、JavaScriptオブジェクトによって保持される外部で割り当てられたメモリの量(つまり、ネイティブアドオンによって割り当てられた独自のメモリを指すJavaScriptオブジェクト)をV8に示します。外部で割り当てられたメモリを登録すると、通常よりも頻繁にグローバルガベージコレクションがトリガーされます。
Promise#
Node-APIは、ECMA仕様のセクション25.4で説明されているように、Promise
オブジェクトを作成するための機能を提供します。 Promiseは、オブジェクトのペアとして実装されます。 napi_create_promise()
によってPromiseが作成されると、「遅延」オブジェクトが作成され、Promise
とともに返されます。遅延オブジェクトは、作成されたPromise
にバインドされ、napi_resolve_deferred()
またはnapi_reject_deferred()
を使用してPromise
を解決または拒否する唯一の手段です。 napi_create_promise()
によって作成された遅延オブジェクトは、napi_resolve_deferred()
またはnapi_reject_deferred()
によって解放されます。 Promise
オブジェクトは、JavaScriptに返され、通常の方法で使用できます。
たとえば、Promiseを作成して非同期ワーカーに渡すには、次のようにします。
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;
上記の関数do_something_asynchronous()
は、非同期アクションを実行し、その後、遅延を解決または拒否することにより、Promiseを完了し、遅延を解放します。
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;
napi_create_promise
#
napi_status napi_create_promise(napi_env env,
napi_deferred* deferred,
napi_value* promise);
[in] env
: APIが呼び出される環境。[out] deferred
: 後で、関連付けられたPromiseを解決または拒否するためにnapi_resolve_deferred()
またはnapi_reject_deferred()
に渡すことができる、新しく作成された遅延オブジェクト。[out] promise
: 遅延オブジェクトに関連付けられたJavaScript Promise。
APIが成功した場合はnapi_ok
を返します。
このAPIは、遅延オブジェクトとJavaScript Promiseを作成します。
napi_resolve_deferred
#
napi_status napi_resolve_deferred(napi_env env,
napi_deferred deferred,
napi_value resolution);
[in] env
: APIが呼び出される環境。[in] deferred
: 解決する関連付けられたPromiseの遅延オブジェクト。[in] resolution
: Promiseを解決する値。
このAPIは、関連付けられている遅延オブジェクトを介してJavaScript Promiseを解決します。したがって、対応する遅延オブジェクトが利用可能なJavaScript Promiseの解決にのみ使用できます。これは事実上、Promiseがnapi_create_promise()
を使用して作成されている必要があり、その呼び出しから返された遅延オブジェクトがこのAPIに渡されるために保持されている必要があることを意味します。
遅延オブジェクトは、正常に完了すると解放されます。
napi_reject_deferred
#
napi_status napi_reject_deferred(napi_env env,
napi_deferred deferred,
napi_value rejection);
[in] env
: APIが呼び出される環境。[in] deferred
: 解決する関連付けられたPromiseの遅延オブジェクト。[in] rejection
: Promiseを拒否する値。
このAPIは、関連付けられている遅延オブジェクトを介してJavaScript Promiseを拒否します。したがって、対応する遅延オブジェクトが利用可能なJavaScript Promiseの拒否にのみ使用できます。これは事実上、Promiseがnapi_create_promise()
を使用して作成されている必要があり、その呼び出しから返された遅延オブジェクトがこのAPIに渡されるために保持されている必要があることを意味します。
遅延オブジェクトは、正常に完了すると解放されます。
napi_is_promise
#
napi_status napi_is_promise(napi_env env,
napi_value value,
bool* is_promise);
[in] env
: APIが呼び出される環境。[in] value
: 調べる値[out] is_promise
:promise
がネイティブPromiseオブジェクト(つまり、基盤となるエンジンによって作成されたPromiseオブジェクト)であるかどうかを示すフラグ。
スクリプト実行#
Node-APIは、基盤となるJavaScriptエンジンを使用してJavaScriptを含む文字列を実行するためのAPIを提供します。
napi_run_script
#
NAPI_EXTERN napi_status napi_run_script(napi_env env,
napi_value script,
napi_value* result);
[in] env
: APIが呼び出される環境。[in] script
: 実行するスクリプトを含むJavaScript文字列。[out] result
: スクリプトの実行によって得られた値。
この関数は、次の注意事項に従ってJavaScriptコードの文字列を実行し、その結果を返します。
libuvイベントループ#
Node-APIは、特定のnapi_env
に関連付けられた現在のイベントループを取得するための関数を提供します。
napi_get_uv_event_loop
#
NAPI_EXTERN napi_status napi_get_uv_event_loop(node_api_nogc_env env,
struct uv_loop_s** loop);
[in] env
: APIが呼び出される環境。[out] loop
: 現在のlibuvループインスタンス。
非同期スレッドセーフ関数呼び出し#
JavaScript関数は通常、ネイティブアドオンのメインスレッドからのみ呼び出すことができます。アドオンが追加のスレッドを作成する場合、napi_env
、napi_value
、またはnapi_ref
を必要とするNode-API関数は、それらのスレッドから呼び出すことはできません。
アドオンに追加のスレッドがあり、それらのスレッドによって完了した処理に基づいてJavaScript関数を呼び出す必要がある場合、それらのスレッドはアドオンのメインスレッドと通信して、メインスレッドが代わりにJavaScript関数を呼び出すことができるようにする必要があります。スレッドセーフ関数APIは、これを行う簡単な方法を提供します。
これらのAPIは、型napi_threadsafe_function
と、この型のオブジェクトを作成、破棄、および呼び出すAPIを提供します。 napi_create_threadsafe_function()
は、複数のスレッドから呼び出すことができるJavaScript関数を保持するnapi_value
への永続的な参照を作成します。呼び出しは非同期に行われます。これは、JavaScriptコールバックが呼び出される値がキューに配置され、キュー内の各値に対して、最終的にJavaScript関数が呼び出されることを意味します。
napi_threadsafe_function
の作成時に、napi_finalize
コールバックを提供できます。このコールバックは、スレッドセーフ関数が破棄されようとするときにメインスレッドで呼び出されます。コンテキストと構築時に与えられたファイナライズデータを受け取り、例えば uv_thread_join()
を呼び出すことによって、スレッドの終了後のクリーンアップの機会を提供します。メインループスレッドを除き、ファイナライズコールバックが完了した後、スレッドセーフ関数を使用するスレッドは存在してはなりません。
napi_create_threadsafe_function()
の呼び出し時に与えられた context
は、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 はキューに空きができるまでブロックします。スレッドセーフ関数が最大キューサイズ 0 で作成された場合、napi_call_threadsafe_function()
は決してブロックしません。
napi_call_threadsafe_function()
は、キューがいっぱいの場合、JavaScript スレッドをデッドロックさせる可能性があるため、JavaScript スレッドから napi_tsfn_blocking
を指定して呼び出すべきではありません。
JavaScript への実際の呼び出しは、call_js_cb
パラメータを介して与えられたコールバックによって制御されます。call_js_cb
は、napi_call_threadsafe_function()
の正常な呼び出しによってキューに配置された値ごとに、メインスレッド上で一度呼び出されます。そのようなコールバックが与えられない場合、デフォルトのコールバックが使用され、結果の JavaScript 呼び出しには引数がありません。call_js_cb
コールバックは、パラメータ内の napi_value
として呼び出す JavaScript 関数、napi_threadsafe_function
の作成時に使用された void*
コンテキストポインタ、およびセカンダリスレッドのいずれかによって作成された次のデータポインタを受け取ります。コールバックは、napi_call_function()
などの API を使用して JavaScript を呼び出すことができます。
コールバックは、env
と call_js_cb
の両方が NULL
に設定されて呼び出されることもあり、これは JavaScript への呼び出しがもはや不可能であることを示していますが、解放が必要なアイテムがキューに残っている可能性があります。これは通常、スレッドセーフ関数がまだアクティブな状態で Node.js プロセスが終了するときに発生します。
Node-API はコールバックに適したコンテキストで call_js_cb
を実行するため、napi_make_callback()
を介して JavaScript を呼び出す必要はありません。
イベントループの各ティックで、ゼロ個以上のキューに入れられたアイテムが呼び出される可能性があります。アプリケーションは、コールバックの呼び出しが進捗し、時間が進むにつれてイベントが呼び出されること以外に、特定の動作に依存すべきではありません。
スレッドセーフ関数の参照カウント#
スレッドは、その存在中に napi_threadsafe_function
オブジェクトに追加したり、そこから削除したりできます。したがって、作成時にスレッドの初期数を指定するのに加えて、napi_acquire_threadsafe_function
を呼び出して、新しいスレッドがスレッドセーフ関数の使用を開始することを示すことができます。同様に、napi_release_threadsafe_function
を呼び出して、既存のスレッドがスレッドセーフ関数の使用を停止することを示すことができます。
napi_threadsafe_function
オブジェクトは、オブジェクトを使用するすべてのスレッドが napi_release_threadsafe_function()
を呼び出したとき、または napi_call_threadsafe_function
の呼び出しへの応答で napi_closing
の戻りステータスを受け取ったときに破棄されます。キューは、napi_threadsafe_function
が破棄される前に空にされます。napi_release_threadsafe_function()
は、特定の napi_threadsafe_function
に関連して行われる最後の API 呼び出しである必要があります。なぜなら、呼び出しが完了した後、napi_threadsafe_function
がまだ割り当てられているという保証がないからです。同じ理由で、napi_call_threadsafe_function
の呼び出しへの応答で napi_closing
の戻り値を受け取った後、スレッドセーフ関数を使用しないでください。napi_threadsafe_function
に関連付けられたデータは、napi_create_threadsafe_function()
に渡された napi_finalize
コールバックで解放できます。napi_create_threadsafe_function
のパラメータ initial_thread_count
は、作成時に napi_acquire_threadsafe_function
を複数回呼び出すのではなく、スレッドセーフ関数の初期取得数をマークします。
napi_threadsafe_function
を使用するスレッドの数がゼロに達すると、napi_acquire_threadsafe_function()
を呼び出すことで、それ以上のスレッドが使用を開始することはできません。実際、napi_release_threadsafe_function()
を除く、関連するすべての後続の API 呼び出しは、napi_closing
のエラー値を返します。
スレッドセーフ関数は、napi_release_threadsafe_function()
に napi_tsfn_abort
の値を指定することで「中止」できます。これにより、参照カウントがゼロに達する前でも、napi_release_threadsafe_function()
を除く、スレッドセーフ関数に関連付けられたすべての後続の API が napi_closing
を返すようになります。特に、napi_call_threadsafe_function()
は napi_closing
を返し、スレッドセーフ関数への非同期呼び出しを行うことがもはや不可能であることをスレッドに通知します。これは、スレッドを終了するための基準として使用できます。napi_call_threadsafe_function()
から napi_closing
の戻り値を受け取った場合、スレッドはスレッドセーフ関数が割り当てられていることが保証されなくなったため、それ以上使用してはなりません。
プロセスを実行し続けるかどうかの決定#
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);
[in] env
: APIが呼び出される環境。[in] func
: 別のスレッドから呼び出すオプションの JavaScript 関数。call_js_cb
にNULL
が渡された場合は、必ず指定する必要があります。[in] async_resource
:async_hooks
のinit
フックに渡される可能性のある、非同期作業に関連付けられたオプションのオブジェクト。[in] async_resource_name
:async_hooks
API によって公開される診断情報のために提供されているリソースの種類を識別するための JavaScript 文字列。[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 関数。
変更履歴
-
実験的 (
NAPI_EXPERIMENTAL
が定義されている場合)call_js_cb
でスローされたキャッチされない例外は、無視される代わりに'uncaughtException'
イベントで処理されます。
napi_get_threadsafe_function_context
#
NAPI_EXTERN napi_status
napi_get_threadsafe_function_context(napi_threadsafe_function func,
void** result);
[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);
[in] func
: 呼び出す非同期スレッドセーフ JavaScript 関数。[in] data
: スレッドセーフ JavaScript 関数の作成中に提供されたコールバックcall_js_cb
を介して JavaScript に送信するデータ。[in] is_blocking
: キューがいっぱいの場合に呼び出しをブロックする必要があることを示すnapi_tsfn_blocking
、またはキューがいっぱいの場合にnapi_queue_full
のステータスですぐに戻る必要があることを示すnapi_tsfn_nonblocking
のいずれかの値をとることができるフラグ。
キューがいっぱいの場合、JavaScript スレッドをデッドロックさせる可能性があるため、この API は JavaScript スレッドから napi_tsfn_blocking
を指定して呼び出すべきではありません。
napi_release_threadsafe_function()
がどのスレッドからでも abort
を napi_tsfn_abort
に設定して呼び出された場合、この API は napi_closing
を返します。API が napi_ok
を返した場合にのみ、値がキューに追加されます。
この API は、func
を使用するどのスレッドからでも呼び出すことができます。
napi_acquire_threadsafe_function
#
NAPI_EXTERN napi_status
napi_acquire_threadsafe_function(napi_threadsafe_function func);
[in] func
: 使用を開始する非同期スレッドセーフ JavaScript 関数。
スレッドは、func
を他のスレッドセーフ関数 API に渡す前に、この 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);
[in] func
: 参照カウントをデクリメントする非同期スレッドセーフ JavaScript 関数。[in] mode
: 現在のスレッドがスレッドセーフ関数へのそれ以上の呼び出しを行わないことを示すnapi_tsfn_release
、または現在のスレッドに加えて、他のスレッドもスレッドセーフ関数へのそれ以上の呼び出しを行うべきではないことを示すnapi_tsfn_abort
のいずれかの値をとることができるフラグ。napi_tsfn_abort
に設定すると、napi_call_threadsafe_function()
の後続の呼び出しはnapi_closing
を返し、それ以上の値はキューに配置されません。
スレッドは、func
の使用を停止するときにこの API を呼び出す必要があります。この API を呼び出した後、func
をスレッドセーフ API に渡すと、func
が破棄された可能性があるため、未定義の結果になります。
この API は、func
の使用を停止するどのスレッドからでも呼び出すことができます。
napi_ref_threadsafe_function
#
NAPI_EXTERN napi_status
napi_ref_threadsafe_function(node_api_nogc_env env, napi_threadsafe_function func);
[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_nogc_env env, napi_threadsafe_function func);
[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_nogc_env env, const char** result);
[in] env
: APIが呼び出される環境。[out] result
: アドオンがロードされた場所の絶対パスを含む URL。ローカルファイルシステム上のファイルの場合、file://
で始まります。文字列は null 終端されており、env
によって所有されているため、変更または解放してはなりません。
result
は、アドオンのロード中にアドオンのファイル名を確立できなかった場合、空の文字列になる可能性があります。