Node-API#

安定性: 2 - Stable

Node-API (旧称 N-API) は、ネイティブアドオンをビルドするための API です。これは、基盤となる JavaScript ランタイム (例えば V8) から独立しており、Node.js 自体の一部としてメンテナンスされています。この API は、Node.js のバージョン間でアプリケーションバイナリインターフェース (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 の戻り値は、out パラメータを介して渡されます。
  • すべての JavaScript の値は、napi_value という名前の不透明な型の背後で抽象化されます。
  • エラーステータスコードの場合、napi_get_last_error_info を使用して追加情報を取得できます。詳細は、エラーハンドリングのセクションにあります。

様々なプログラミング言語でのアドオンの記述#

Node-API は、Node.js のバージョンや異なるコンパイラレベル間での ABI 安定性を保証する C API です。この安定性の保証により、Node-API の上で他のプログラミング言語でアドオンを記述することが可能です。他のプログラミング言語やエンジンのサポート詳細については、言語とエンジンのバインディングを参照してください。

node-addon-api は、Node-API を呼び出す C++ コードをより効率的に記述する方法を提供する公式の C++ バインディングです。このラッパーは、インライン化可能な C++ API を提供するヘッダーオンリーライブラリです。node-addon-api でビルドされたバイナリは、Node.js によってエクスポートされる Node-API の C ベース関数のシンボルに依存します。以下のコードスニペットは node-addon-api の例です。

Object obj = Object::New(env);
obj["foo"] = String::New(env, "bar"); 

上記の node-addon-api C++ コードは、以下の C ベースの Node-API コードと等価です。

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++ で書かれていても、C の Node-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 安定性を保証していることを確認することによって。

ABI安定性における列挙型の値#

Node-API で定義されるすべての列挙型データ型は、固定サイズの int32_t 値と見なされるべきです。ビットフラグ列挙型は明示的に文書化されるべきであり、ビット値としてビットOR (|) のようなビット演算子で動作します。特に文書化されていない限り、列挙型は拡張可能であると見なされるべきです。

新しい列挙値は、列挙定義の最後に追加されます。列挙値が削除されたり、名前が変更されたりすることはありません。

Node-API 関数から返される、または Node-API 関数の out パラメータとして提供される列挙型の場合、その値は整数値であり、アドオンは未知の値を処理すべきです。新しい値はバージョンガードなしで導入されることが許可されています。例えば、switch 文で napi_status をチェックする場合、新しいステータスコードが新しい Node.js バージョンで導入される可能性があるため、アドオンは default ブランチを含めるべきです。

in-parameter で使用される列挙型の場合、未知の整数値を Node-API 関数に渡した結果は、特に文書化されていない限り未定義です。新しい値は、それが導入された Node-API バージョンを示すバージョンガードと共に追加されます。例えば、napi_get_all_property_namesnapi_key_filter の新しい列挙値で拡張される可能性があります。

in-parameter と out-parameter の両方で使用される列挙型の場合、新しい値はバージョンガードなしで導入されることが許可されています。

ビルド#

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 CIAppVeyor などの 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 releases にのみバイナリをアップロードします。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 と安定 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 になります。

この表は古いストリームでは最新ではない可能性があります。最新の情報は、最新の API ドキュメントの Node-API バージョンマトリックスにあります。

Node-API バージョン サポートされているバージョン
10 v22.14.0+, 23.6.0+ およびそれ以降のすべてのバージョン
9 v18.17.0+, 20.3.0+, 21.0.0 およびそれ以降のすべてのバージョン
8 v12.22.0+, v14.17.0+, v15.12.0+, 16.0.0 およびそれ以降のすべてのバージョン
7 v10.23.0+, v12.19.0+, v14.12.0+, 15.0.0 およびそれ以降のすべてのバージョン
6 v10.20.0+, v12.17.0+, 14.0.0 およびそれ以降のすべてのバージョン
5 v10.17.0+, v12.11.0+, 13.0.0 およびそれ以降のすべてのバージョン
4 v10.16.0+, v11.8.0+, 12.0.0 およびそれ以降のすべてのバージョン
3 v6.14.2*, 8.11.2+, v9.11.0+*, 10.0.0 およびそれ以降のすべてのバージョン
2 v8.10.0+*, v9.3.0+*, 10.0.0 およびそれ以降のすべてのバージョン
1 v8.6.0+**, v9.0.0+*, 10.0.0 およびそれ以降のすべてのバージョン

* Node-API は実験的でした。

** Node.js 8.0.0 は Node-API を実験的に含んでいました。Node-API バージョン 1 としてリリースされましたが、Node.js 8.6.0 まで進化を続けました。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.js バージョンを使用している場合、または Node-API version: がリストされていない場合は、node_api.h または js_native_api.h のインクルードの前に #define NAPI_EXPERIMENTAL がある場合にのみ API が利用可能になります。API が added in: に示されているバージョンよりも後の Node.js バージョンで利用できないように見える場合、これがその見かけ上の不在の理由である可能性が最も高いです。

ネイティブコードから ECMAScript の機能にアクセスすることに厳密に関連する Node-API は、js_native_api.hjs_native_api_types.h に別々に見つけることができます。これらのヘッダーで定義されている API は、node_api.hnode_api_types.h に含まれています。ヘッダーがこのように構成されているのは、Node.js の外部で Node-API の実装を可能にするためです。それらの実装では、Node.js 固有の API は適用できない場合があります。

アドオンの Node.js 固有の部分は、実際の機能を JavaScript 環境に公開するコードから分離できるため、後者は Node-API の複数の実装で使用できます。以下の例では、addon.caddon.hjs_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 言語仕様セクション エージェントは、「エージェント」の概念を、JavaScript コードが実行される自己完結型の環境として定義しています。複数のそのようなエージェントが、プロセスによって並行または順次で開始および終了されることがあります。

Node.js 環境は、ECMAScript エージェントに対応します。メインプロセスでは、起動時に環境が作成され、ワーカースレッドとして機能するために別のスレッドで追加の環境を作成できます。Node.js が別のアプリケーションに埋め込まれている場合、アプリケーションのメインスレッドは、アプリケーションプロセスのライフサイクル中に Node.js 環境を複数回構築および破棄することもあり、アプリケーションによって作成された各 Node.js 環境は、そのライフサイクル中にワーカースレッドとして追加の環境を作成および破棄することがあります。

ネイティブアドオンの観点から見ると、これは、それが提供するバインディングが、複数のコンテキストから、そして複数のスレッドから並行して複数回呼び出される可能性があることを意味します。

ネイティブアドオンは、アドオンの各インスタンスに固有の状態を、Node.js 環境のライフサイクル中に使用するグローバルな状態を割り当てる必要がある場合があります。

この目的のために、Node-API は、そのライフサイクルが Node.js 環境のライフサイクルに結びついているようにデータを関連付ける方法を提供します。

napi_set_instance_data#

napi_status napi_set_instance_data(node_api_basic_env env,
                                   void* data,
                                   napi_finalize finalize_cb,
                                   void* finalize_hint); 
  • [in] env: Node-API 呼び出しが実行される環境。
  • [in] data: このインスタンスのバインディングで利用可能にするデータアイテム。
  • [in] finalize_cb: 環境が破棄されるときに呼び出される関数。この関数は data を受け取るので、それを解放することができます。napi_finalize で詳細が提供されます。
  • [in] finalize_hint: コレクション中にファイナライズコールバックに渡すオプションのヒント。

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_basic_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 環境に関連付けられたデータを取得します。データが設定されていない場合、呼び出しは成功し、dataNULL に設定されます。

基本的な 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_hooknapi_set_instance_data に与えられたコールバックを通じて配信されます。

node_api_basic_env#

安定性: 1 - Experimental

この napi_env の変異体は、同期ファイナライザ (node_api_basic_finalize) に渡されます。最初の引数として node_api_basic_env 型のパラメータを受け入れる Node-API のサブセットがあります。これらの API は JavaScript エンジンの状態にアクセスしないため、同期ファイナライザから安全に呼び出すことができます。これらの API に napi_env 型のパラメータを渡すことは許可されていますが、JavaScript エンジンの状態にアクセスする API に node_api_basic_env 型のパラメータを渡すことは許可されていません。キャストなしでそうしようとすると、誤ったポインタ型が関数に渡されたときに警告やエラーを発するフラグでアドオンがコンパイルされた場合に、コンパイラの警告やエラーが発生します。同期ファイナライザからそのような API を呼び出すと、最終的にアプリケーションが終了します。

napi_value#

これは、JavaScript の値を表すために使用される不透明なポインタです。

napi_threadsafe_function#

これは、napi_call_threadsafe_function() を介して複数のスレッドから非同期に呼び出すことができる JavaScript 関数を表す不透明なポインタです。

napi_threadsafe_function_release_mode#

napi_release_threadsafe_function() に渡す値で、スレッドセーフな関数を即座に閉じる (napi_tsfn_abort) か、単に解放する (napi_tsfn_release) かを示し、後者の場合は napi_acquire_threadsafe_function()napi_call_threadsafe_function() を介して後で使用できるようになります。

typedef enum {
  napi_tsfn_release,
  napi_tsfn_abort
} napi_threadsafe_function_release_mode; 

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 よりも強力なチェックです。後者は、オブジェクトのプロトタイプが操作されている場合に偽陽性を報告する可能性があるためです。型タグ付けは napi_wrap と組み合わせて使用すると最も便利です。なぜなら、ラップされたオブジェクトから取得されたポインタが、以前に JavaScript オブジェクトに適用された型タグに対応するネイティブ型に安全にキャストできることを保証するからです。

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_basic_finalize#

安定性: 1 - Experimental

外部で所有されているデータが、関連付けられていたオブジェクトがガベージコレクションされたためにクリーンアップの準備ができたときにユーザーに通知できるようにする、アドオン提供の関数の関数ポインタ型。ユーザーは、オブジェクトのコレクション時に呼び出される、次のシグネチャを満たす関数を提供する必要があります。現在、node_api_basic_finalize は、外部データを持つオブジェクトがいつ収集されるかを知るために使用できます。

typedef void (*node_api_basic_finalize)(node_api_basic_env env,
                                      void* finalize_data,
                                      void* finalize_hint); 

オブジェクトのライフタイム管理で議論されている理由がない限り、関数本体内でハンドルやコールバックスコープを作成する必要はありません。

これらの関数は、JavaScript エンジンが JavaScript コードを実行できない状態にあるときに呼び出される可能性があるため、最初のパラメータとして node_api_basic_env を受け入れる Node-API のみが呼び出される可能性があります。node_api_post_finalizer を使用して、現在のガベージコレクションサイクルが完了した後に実行される、JavaScript エンジンの状態へのアクセスを必要とする Node-API 呼び出しをスケジュールできます。

node_api_create_external_string_latin1node_api_create_external_string_utf16 の場合、env パラメータは null である可能性があります。なぜなら、外部文字列は環境のシャットダウンの後半で収集される可能性があるからです。

変更履歴

  • experimental (NAPI_EXPERIMENTAL)

    最初のパラメータとして node_api_basic_env を受け入れる Node-API 呼び出しのみが呼び出される可能性があります。そうでない場合、アプリケーションは適切なエラーメッセージで終了します。この機能は NODE_API_EXPERIMENTAL_BASIC_ENV_OPT_OUT を定義することでオフにすることができます。

napi_finalize#

ガベージコレクションイベントに応答して、ガベージコレクションサイクルが完了した後に、Node-APIへの呼び出しのグループをスケジュールすることをユーザーに許可するアドオン提供の関数の関数ポインタ型。これらの関数ポインタは、node_api_post_finalizerで使用できます。

typedef void (*napi_finalize)(napi_env env,
                              void* finalize_data,
                              void* finalize_hint); 

変更履歴

  • experimental (NAPI_EXPERIMENTAL が定義されている)

    この型の関数は、node_api_post_finalizer を除き、ファイナライザとして使用できなくなりました。代わりに node_api_basic_finalize を使用する必要があります。この機能は NODE_API_EXPERIMENTAL_BASIC_ENV_OPT_OUT を定義することでオフにすることができます。

napi_async_execute_callback#

非同期操作をサポートする関数で使用される関数ポインタ。コールバック関数は、次のシグネチャを満たす必要があります。

typedef void (*napi_async_execute_callback)(napi_env env, void* data); 

この関数の実装では、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: セカンダリスレッドによって作成されたデータ。このネイティブデータを、js_callback が呼び出されたときにパラメータとして渡すことができる JavaScript の値 (Node-API 関数を使用) に変換するのは、コールバックの責任です。このポインタは、スレッドとこのコールバックによって完全に管理されます。したがって、このコールバックはデータを解放する必要があります。

オブジェクトのライフタイム管理で議論されている理由がない限り、関数本体内でハンドルやコールバックスコープを作成する必要はありません。

napi_cleanup_hook#

napi_add_env_cleanup_hook で使用される関数ポインタ。環境が破棄されるときに呼び出されます。

コールバック関数は、次のシグネチャを満たす必要があります。

typedef void (*napi_cleanup_hook)(void* data); 
napi_async_cleanup_hook#

napi_add_async_cleanup_hook で使用される関数ポインタ。環境が破棄されるときに呼び出されます。

コールバック関数は、次のシグネチャを満たす必要があります。

typedef void (*napi_async_cleanup_hook)(napi_async_cleanup_hook_handle handle,
                                        void* data); 

この関数の本体は、非同期クリーンアップアクションを開始する必要があり、その最後に handlenapi_remove_async_cleanup_hook の呼び出しで渡さなければなりません。

エラーハンドリング#

Node-API は、エラーハンドリングにリターン値と JavaScript 例外の両方を使用します。以下のセクションでは、それぞれのケースのアプローチについて説明します。

戻り値#

すべての Node-API 関数は同じエラーハンドリングパターンを共有しています。すべての API 関数の戻り値の型は napi_status です。

リクエストが成功し、キャッチされない JavaScript 例外がスローされなかった場合、戻り値は napi_ok になります。エラーが発生し、AND 例外がスローされた場合、エラーに対応する 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_basic_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_statusnapi_ok の場合、保留中の例外はなく、追加のアクションは必要ありません。返された napi_statusnapi_ok または napi_pending_exception 以外のものの場合、単にすぐに戻るのではなく、回復して続行しようとするには、例外が保留中かどうかを判断するために napi_is_exception_pending を呼び出す必要があります。

多くの場合、Node-API 関数が呼び出され、例外がすでに保留中の場合、関数はすぐに napi_pending_exceptionnapi_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_errornapi_throw_type_errornapi_throw_range_errornode_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_ 関数はオプションのコードパラメータを取ります。これは、エラーオブジェクトに追加されるコードの文字列です。オプションのパラメータが 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: location の長さ (バイト単位)、または null 終端の場合は NAPI_AUTO_LENGTH
  • [in] message: エラーに関連付けられたメッセージ。
  • [in] message_len: message の長さ (バイト単位)、または 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_scopenapi_close_handle_scope です。

Node-API は、スコープの単一のネストされた階層のみをサポートします。常にアクティブなスコープは1つだけであり、すべての新しいハンドルはアクティブな間はそのスコープに関連付けられます。スコープは、開かれた順序とは逆の順序で閉じなければなりません。さらに、ネイティブメソッド内で作成されたすべてのスコープは、そのメソッドから戻る前に閉じなければなりません。

先の例に napi_open_handle_scopenapi_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_scopenapi_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: エスケープする JavaScript Object を表す napi_value
  • [out] result: 外部スコープでエスケープされた Object へのハンドルを表す napi_value

API が成功した場合は napi_ok を返します。

この API は、JavaScript オブジェクトへのハンドルを昇格させ、外部スコープの寿命の間有効になるようにします。スコープごとに一度しか呼び出せません。複数回呼び出すとエラーが返されます。

この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_refnapi_reference_unref を通じて変更できます。参照のカウントが 0 の間にオブジェクトが収集された場合、参照に関連付けられたオブジェクトを取得するための後続のすべての呼び出し napi_get_reference_value は、返される napi_value に対して NULL を返します。オブジェクトが収集された参照に対して napi_reference_ref を呼び出そうとすると、エラーが発生します。

参照 (reference) は、アドオンで不要になったら削除しなければなりません。参照が削除されると、対応するオブジェクトがガベージコレクションされるのを妨げなくなります。永続的な参照 (persistent reference) を削除し忘れると、永続的な参照のためのネイティブメモリとヒープ上の対応するオブジェクトの両方が永久に保持される「メモリリーク」が発生します。

同じオブジェクトを参照する複数の永続的な参照を作成することができ、それぞれが個々の参照カウントに基づいてオブジェクトを生存させ続けるかどうかを決定します。同じオブジェクトへの複数の永続的な参照は、予期せずネイティブメモリを生存させ続ける結果になることがあります。永続的な参照のネイティブ構造は、参照されるオブジェクトのファイナライザが実行されるまで生存させ続ける必要があります。同じオブジェクトに対して新しい永続的な参照が作成されると、そのオブジェクトのファイナライザは実行されず、以前の永続的な参照が指していたネイティブメモリは解放されません。これは、可能な場合に napi_reference_unref に加えて napi_delete_reference を呼び出すことで回避できます。

変更履歴

  • バージョン10(NAPI_VERSION10 以上として定義されている場合)

    参照はすべての値の型に対して作成できます。新しくサポートされた値の型は、弱い参照のセマンティクスをサポートせず、これらの型の値は参照カウントが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_basic_env env,
                                                  napi_cleanup_hook fun,
                                                  void* arg); 

現在のNode.js環境が終了したときに、arg パラメータを付けて実行される関数として fun を登録します。

関数は、異なる arg 値で複数回安全に指定できます。その場合、関数も複数回呼び出されます。同じ funarg の値を複数回提供することは許可されておらず、プロセスが異常終了する原因となります。

フックは逆の順序で呼び出されます。つまり、最も最近追加されたものが最初に呼び出されます。

このフックの削除は napi_remove_env_cleanup_hook を使用して行うことができます。通常、これはこのフックが追加されたリソースがとにかく破棄されるときに行われます。

非同期クリーンアップについては、napi_add_async_cleanup_hook が利用可能です。

napi_remove_env_cleanup_hook#
NAPI_EXTERN napi_status napi_remove_env_cleanup_hook(node_api_basic_env env,
                                                     void (*fun)(void* arg),
                                                     void* arg); 

現在の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_basic_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_handlearg パラメータで実行される関数として、napi_async_cleanup_hook 型の関数である hook を登録します。

napi_add_env_cleanup_hook とは異なり、フックは非同期であることが許可されます。

それ以外の動作は、一般的に napi_add_env_cleanup_hook の動作と一致します。

remove_handleNULL でない場合、不透明な値が格納されます。この値は、フックがすでに呼び出されたかどうかに関わらず、後で 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); 

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_hooknapi_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 パラメータを介して空のオブジェクトが渡されます。InitNULL を返した場合、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;
} 

envexports パラメータは NAPI_MODULE_INIT マクロの本体に提供されます。

すべてのNode-APIアドオンはコンテキストアウェアであり、複数回ロードされる可能性があります。そのようなモジュールを宣言する際には、いくつかの設計上の考慮事項があります。コンテキストアウェアなアドオンに関するドキュメントに詳細が記載されています。

変数 envexports は、マクロ呼び出しに続く関数本体の内部で利用可能になります。

オブジェクトへのプロパティ設定の詳細については、JavaScriptプロパティの操作のセクションを参照してください。

アドオンモジュールのビルドに関する一般的な詳細については、既存のAPIを参照してください。

JavaScript値の操作#

Node-APIは、すべての種類のJavaScript値を作成するための一連のAPIを公開しています。これらの型の一部は、ECMAScript言語仕様セクション言語型に記載されています。

基本的に、これらのAPIは以下のいずれかを行うために使用されます。

  1. 新しいJavaScriptオブジェクトを作成する
  2. Cのプリミティブ型からNode-APIの値に変換する
  3. Node-APIの値からCのプリミティブ型に変換する
  4. undefinednullを含むグローバルインスタンスを取得する

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; 

プロパティフィルタのビットフラグ。ビット演算子と共に使用して複合フィルタを構築します。

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言語仕様の セクション 言語の型 で記述されている型に対応します。そのセクションの型に加えて、napi_valuetype は外部データを持つ FunctionObject も表現できます。

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言語仕様セクション TypedArray オブジェクトに対応します。

オブジェクト作成関数#

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言語仕様のセクション 配列オブジェクトに記述されています。

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言語仕様のセクション 配列オブジェクトに記載されています。

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 の基底となるバイトバッファへのポインタ。dataNULL を渡すことで任意に無視できます。
  • [out] result: JavaScriptの ArrayBuffer を表す napi_value

API が成功した場合は napi_ok を返します。

この API は、JavaScript の ArrayBuffer に対応する Node-API の値を返します。ArrayBuffer は、固定長のバイナリデータバッファを表すために使用されます。通常、TypedArray オブジェクトのバッキングバッファとして使用されます。割り当てられる ArrayBuffer は、渡された length パラメータによってサイズが決定される基底のバイトバッファを持ちます。呼び出し元がバッファを直接操作したい場合に備えて、この基底バッファはオプションで呼び出し元に返されます。このバッファは、ネイティブコードからのみ直接書き込むことができます。JavaScript からこのバッファに書き込むには、型付き配列または DataView オブジェクトを作成する必要があります。

JavaScriptの ArrayBuffer オブジェクトは、ECMAScript言語仕様のセクション ArrayBuffer オブジェクトに記載されています。

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: 基底となるバッファへの生のポインタ。dataNULL を渡すことで任意に無視できます。
  • [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_dataNULL を渡すことで任意に無視できます。
  • [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言語仕様のセクション Dateオブジェクトに記載されています。

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: コレクション中にファイナライズコールバックに渡すオプションのヒント。
  • [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: コレクション中にファイナライズコールバックに渡すオプションのヒント。
  • [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つの関数が非表示になります。これにより、誤ってこれらのメソッドのいずれかを使用した場合にコンパイルエラーが発生することが保証されます。

このAPIは、JavaScriptの ArrayBuffer に対応するNode-APIの値を返します。ArrayBuffer の基底となるバイトバッファは外部で割り当てられ、管理されます。呼び出し元は、ファイナライズコールバックが呼ばれるまでバイトバッファが有効であることを保証しなければなりません。

このAPIは、作成されたJavaScriptオブジェクトがガベージコレクションされたときに呼び出される napi_finalize コールバックを追加します。

JavaScriptの ArrayBuffer は、ECMAScript言語仕様のセクション ArrayBufferオブジェクトに記載されています。

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: コレクション中にファイナライズコールバックに渡すオプションのヒント。
  • [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つの関数が非表示になります。これにより、誤ってこれらのメソッドのいずれかを使用した場合にコンパイルエラーが発生することが保証されます。

このAPIは、node::Bufferオブジェクトを割り当て、渡されたバッファに裏打ちされたデータで初期化します。これはまだ完全にサポートされたデータ構造ですが、ほとんどの場合、TypedArrayを使用すれば十分です。

このAPIは、作成されたJavaScriptオブジェクトがガベージコレクションされたときに呼び出される napi_finalize コールバックを追加します。

Node.js >=4 では、BufferUint8Array です。

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言語仕様のセクション オブジェクト型に記載されています。

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言語仕様のセクション シンボル型に記載されています。

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: 説明文字列の長さ(バイト単位)、またはヌル終端の場合は NAPI_AUTO_LENGTH
  • [out] result: JavaScriptの symbol を表す napi_value

API が成功した場合は napi_ok を返します。

このAPIは、グローバルレジストリで特定の説明を持つ既存のシンボルを検索します。シンボルが既に存在する場合はそれが返され、そうでない場合はレジストリに新しいシンボルが作成されます。

JavaScriptの symbol 型は、ECMAScript言語仕様のセクション シンボル型に記載されています。

napi_create_typedarray#
napi_status napi_create_typedarray(napi_env env,
                                   napi_typedarray_type type,
                                   size_t length,
                                   napi_value arraybuffer,
                                   size_t byte_offset,
                                   napi_value* result) 
  • [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言語仕様のセクション TypedArrayオブジェクトに記載されています。

node_api_create_buffer_from_arraybuffer#
napi_status NAPI_CDECL node_api_create_buffer_from_arraybuffer(napi_env env,
                                                              napi_value arraybuffer,
                                                              size_t byte_offset,
                                                              size_t byte_length,
                                                              napi_value* result) 
  • [in] env: APIが呼び出される環境。
  • [in] arraybuffer: バッファが作成される元の ArrayBuffer
  • [in] byte_offset: ArrayBuffer 内でバッファの作成を開始するバイトオフセット。
  • [in] byte_length: ArrayBuffer から作成されるバッファの長さ(バイト単位)。
  • [out] result: 作成されたJavaScript Buffer オブジェクトを表す napi_value

API が成功した場合は napi_ok を返します。

このAPIは、既存の ArrayBuffer からJavaScriptの Buffer オブジェクトを作成します。Buffer オブジェクトはNode.js固有のクラスで、JavaScriptで直接バイナリデータを扱う方法を提供します。

バイト範囲 [byte_offset, byte_offset + byte_length)ArrayBuffer の範囲内にある必要があります。byte_offset + byte_lengthArrayBuffer のサイズを超える場合、RangeError 例外が発生します。

napi_create_dataview#
napi_status napi_create_dataview(napi_env env,
                                 size_t byte_length,
                                 napi_value arraybuffer,
                                 size_t byte_offset,
                                 napi_value* result) 
  • [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言語仕様のセクション DataViewオブジェクトに記載されています。

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言語仕様のセクション number型に記載されています。

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言語仕様のセクション number型に記載されています。

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言語仕様のセクション number型に記載されています。int64_t の全範囲をJavaScriptで完全な精度で表現することはできないことに注意してください。Number.MIN_SAFE_INTEGER -(2**53 - 1) から Number.MAX_SAFE_INTEGER (2**53 - 1) の範囲外の整数値は精度を失います。

napi_create_double#
napi_status napi_create_double(napi_env env, double value, napi_value* result) 
  • [in] env: API が呼び出される環境。
  • [in] value: JavaScriptで表現される倍精度値。
  • [out] result: JavaScriptの number を表す napi_value

API が成功した場合は napi_ok を返します。

このAPIは、Cの double 型からJavaScriptの number 型へ変換するために使用されます。

JavaScriptの number 型は、ECMAScript言語仕様のセクション number型に記載されています。

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: 文字列の長さ(バイト単位)、またはヌル終端の場合は NAPI_AUTO_LENGTH
  • [out] result: JavaScriptの string を表す napi_value

API が成功した場合は napi_ok を返します。

このAPIは、ISO-8859-1でエンコードされたC文字列からJavaScriptの string 値を作成します。ネイティブ文字列はコピーされます。

JavaScriptの string 型は、ECMAScript言語仕様のセクション string型に記載されています。

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: 文字列の長さ(バイト単位)、またはヌル終端の場合は 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: コレクション中にファイナライズコールバックに渡すオプションのヒント。
  • [out] result: JavaScriptの string を表す napi_value
  • [out] copied: 文字列がコピーされたかどうか。コピーされた場合、ファイナライザはすでに str を破棄するために呼び出されています。

API が成功した場合は napi_ok を返します。

このAPIは、ISO-8859-1エンコードのC文字列からJavaScriptの string 値を作成します。ネイティブ文字列はコピーされない場合があり、そのためJavaScript値のライフサイクル全体にわたって存在しなければなりません。

JavaScriptの string 型は、ECMAScript言語仕様のセクション string型に記載されています。

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バイトコード単位)、またはヌル終端の場合は NAPI_AUTO_LENGTH
  • [out] result: JavaScriptの string を表す napi_value

API が成功した場合は napi_ok を返します。

このAPIは、UTF16-LEでエンコードされたC文字列からJavaScriptの string 値を作成します。ネイティブ文字列はコピーされます。

JavaScriptの string 型は、ECMAScript言語仕様のセクション string型に記載されています。

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バイトコード単位)、またはヌル終端の場合は 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: コレクション中にファイナライズコールバックに渡すオプションのヒント。
  • [out] result: JavaScriptの string を表す napi_value
  • [out] copied: 文字列がコピーされたかどうか。コピーされた場合、ファイナライザはすでに str を破棄するために呼び出されています。

API が成功した場合は napi_ok を返します。

このAPIは、UTF16-LEエンコードされたC文字列からJavaScriptの `string` 値を作成します。ネイティブ文字列はコピーされない場合があるため、JavaScript値のライフサイクル全体にわたって存在しなければなりません。

JavaScriptの string 型は、ECMAScript言語仕様のセクション string型に記載されています。

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: 文字列の長さ(バイト単位)、またはヌル終端の場合は NAPI_AUTO_LENGTH
  • [out] result: JavaScriptの string を表す napi_value

API が成功した場合は napi_ok を返します。

このAPIは、UTF8でエンコードされたC文字列からJavaScriptの string 値を作成します。ネイティブ文字列はコピーされます。

JavaScriptの string 型は、ECMAScript言語仕様のセクション string型に記載されています。

最適化されたプロパティキーを作成する関数#

V8を含む多くのJavaScriptエンジンは、プロパティ値の設定と取得のキーとして内部化された文字列を使用します。通常、そのような文字列を作成および検索するためにハッシュテーブルを使用します。キー作成ごとに多少のコストがかかりますが、その後は文字列全体ではなく文字列ポインタの比較が可能になるため、パフォーマンスが向上します。

新しいJavaScript文字列をプロパティキーとして使用する予定がある場合、一部のJavaScriptエンジンではこのセクションの関数を使用する方が効率的です。そうでない場合は、プロパティキー作成メソッドで文字列を作成/格納する際に追加のオーバーヘッドが発生する可能性があるため、napi_create_string_utf8 または node_api_create_external_string_utf8 シリーズの関数を使用してください。

node_api_create_property_key_latin1#
napi_status NAPI_CDECL node_api_create_property_key_latin1(napi_env env,
                                                           const char* str,
                                                           size_t length,
                                                           napi_value* result); 
  • [in] env: API が呼び出される環境。
  • [in] str: ISO-8859-1でエンコードされた文字列を表す文字バッファ。
  • [in] length: 文字列の長さ(バイト単位)、またはヌル終端の場合は NAPI_AUTO_LENGTH
  • [out] result: オブジェクトのプロパティキーとして使用される、最適化されたJavaScriptの string を表す napi_value

API が成功した場合は napi_ok を返します。

このAPIは、オブジェクトのプロパティキーとして使用するために、ISO-8859-1でエンコードされたC文字列から最適化されたJavaScriptの string 値を作成します。ネイティブ文字列はコピーされます。napi_create_string_latin1 とは対照的に、同じ str ポインタでこの関数を後続で呼び出すと、エンジンによっては要求された napi_value の作成が高速化される場合があります。

JavaScriptの string 型は、ECMAScript言語仕様のセクション string型に記載されています。

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バイトコード単位)、またはヌル終端の場合は NAPI_AUTO_LENGTH
  • [out] result: オブジェクトのプロパティキーとして使用される、最適化されたJavaScriptの string を表す napi_value

API が成功した場合は napi_ok を返します。

このAPIは、オブジェクトのプロパティキーとして使用するために、UTF16-LEでエンコードされたC文字列から最適化されたJavaScriptの `string` 値を作成します。ネイティブ文字列はコピーされます。

JavaScriptの string 型は、ECMAScript言語仕様のセクション string型に記載されています。

node_api_create_property_key_utf8#
napi_status NAPI_CDECL node_api_create_property_key_utf8(napi_env env,
                                                         const char* str,
                                                         size_t length,
                                                         napi_value* result); 
  • [in] env: API が呼び出される環境。
  • [in] str: UTF8でエンコードされた文字列を表す文字バッファ。
  • [in] length: 文字列の長さ(2バイトコード単位)、またはヌル終端の場合は NAPI_AUTO_LENGTH
  • [out] result: オブジェクトのプロパティキーとして使用される、最適化されたJavaScriptの string を表す napi_value

API が成功した場合は napi_ok を返します。

このAPIは、オブジェクトのプロパティキーとして使用するために、UTF8でエンコードされたC文字列から最適化されたJavaScriptの string 値を作成します。ネイティブ文字列はコピーされます。

JavaScriptの string 型は、ECMAScript言語仕様のセクション string型に記載されています。

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言語仕様のセクション 配列インスタンスの長さに記載されています。

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 または SharedArrayBuffer を表す napi_value
  • [out] data: ArrayBuffer または SharedArrayBuffer の基底データバッファが 0 の場合、これは NULL または他の任意のポインタ値になる可能性があります。
  • [out] byte_length: 基底データバッファの長さ(バイト単位)。

API が成功した場合は napi_ok を返します。

このAPIは、ArrayBuffer または SharedArrayBuffer の基底となるデータバッファとその長さを取得するために使用されます。

警告:このAPIを使用する際には注意してください。基底となるデータバッファのライフタイムは、返された後も ArrayBuffer または SharedArrayBuffer によって管理されます。このAPIを安全に使用する可能性のある方法は、ArrayBuffer または SharedArrayBuffer のライフタイムの制御を保証するために使用できる napi_create_reference と組み合わせて使用することです。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 の基底データバッファ。長さが 0 の場合、これは NULL またはその他のポインタ値になることがあります。
  • [out] length: 基底データバッファの長さ(バイト単位)。

API が成功した場合は napi_ok を返します。

このメソッドは、napi_get_typedarray_info と同じ databyte_length を返します。また、napi_get_typedarray_info は値として node::Buffer (Uint8Array) も受け付けます。

このAPIは、node::Buffer の基底となるデータバッファとその長さを取得するために使用されます。

警告:このAPIを使用する際は注意してください。基底となるデータバッファがVMによって管理されている場合、そのライフタイムは保証されません。

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 にすることができます。

警告:このAPIを使用する際には注意してください。基底となるデータバッファはVMによって管理されています。

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 プリミティブ値を返します。必要に応じて値を切り捨て、losslessfalse に設定します。

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 プリミティブ値を返します。必要に応じて値を切り捨て、losslessfalse に設定します。

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ビットリトルエンディアン配列、および配列の要素数に変換します。sign_bitwords は、word_count のみを取得するために両方とも 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)は、結果をゼロに設定します。

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)は、結果をゼロに設定します。

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 が渡された場合、文字列の長さ(バイト単位、ヌル終端文字を除く)が result に返されます。
  • [in] bufsize: 宛先バッファのサイズ。この値が不十分な場合、返される文字列は切り詰められ、ヌル終端されます。この値がゼロの場合、文字列は返されず、バッファに変更は加えられません。
  • [out] result: バッファにコピーされたバイト数(ヌル終端文字を除く)。

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 が渡された場合、文字列の長さ(バイト単位、ヌル終端文字を除く)が result に返されます。
  • [in] bufsize: 宛先バッファのサイズ。この値が不十分な場合、返される文字列は切り詰められ、ヌル終端されます。この値がゼロの場合、文字列は返されず、バッファに変更は加えられません。
  • [out] result: バッファにコピーされたバイト数(ヌル終端文字を除く)。

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バイトコード単位、ヌル終端文字を除く)が返されます。
  • [in] bufsize: 宛先バッファのサイズ。この値が不十分な場合、返される文字列は切り詰められ、ヌル終端されます。この値がゼロの場合、文字列は返されず、バッファに変更は加えられません。
  • [out] result: バッファにコピーされた2バイトコード単位の数(ヌル終端文字を除く)。

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セットを公開しています。

これらのAPIは、以下のいずれかの操作をサポートしています。

  1. JavaScriptの値を特定のJavaScript型(numberstring など)に強制変換する。
  2. JavaScriptの値の型をチェックする。
  3. 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言語仕様のセクション ToBooleanで定義されている抽象操作 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言語仕様のセクション ToNumberで定義されている抽象操作 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言語仕様のセクション ToObjectで定義されている抽象操作 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言語仕様のセクション ToStringで定義されている抽象操作 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 がExternal値でもない場合は napi_invalid_arg

このAPIは、ECMAScript言語仕様のセクション typeof演算子で定義されているように、オブジェクトに対して typeof 演算子を呼び出すのと同様の動作を表しますが、いくつかの違いがあります。

  1. External値を検出するサポートがあります。
  2. nullを別の型として検出しますが、ECMAScriptの typeofobject と検出します。

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言語仕様のセクション instanceof演算子で定義されているように、オブジェクトに対して 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言語仕様のセクション IsArrayで定義されているように、オブジェクトに対して 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_valuenode::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_valueError オブジェクトを表すかどうか。

API が成功した場合は napi_ok を返します。

このAPIは、渡された ObjectError であるかを確認します。

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_valueTypedArray を表すかどうか。

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_valueDataView を表すかどうか。

API が成功した場合は napi_ok を返します。

このAPIは、渡された ObjectDataView であるかを確認します。

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言語仕様のセクション IsStrctEqualで定義されているStrict Equalityアルゴリズムの呼び出しを表します。

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言語仕様のセクション detachArrayBufferで定義されている 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 を返します。

ArrayBuffer は、その内部データが null である場合にデタッチされていると見なされます。

このAPIは、ECMAScript言語仕様のセクション isDetachedBufferで定義されている ArrayBufferIsDetachedBuffer 操作の呼び出しを表します。

node_api_is_sharedarraybuffer#

安定性: 1 - Experimental

napi_status node_api_is_sharedarraybuffer(napi_env env, napi_value value, bool* result) 
  • [in] env: API が呼び出される環境。
  • [in] value: チェックするJavaScriptの値。
  • [out] result: 与えられた napi_valueSharedArrayBuffer を表すかどうか。

API が成功した場合は napi_ok を返します。

このAPIは、渡されたオブジェクトが SharedArrayBuffer であるかどうかをチェックします。

node_api_create_sharedarraybuffer#

安定性: 1 - Experimental

napi_status node_api_create_sharedarraybuffer(napi_env env,
                                             size_t byte_length,
                                             void** data,
                                             napi_value* result) 
  • [in] env: API が呼び出される環境。
  • [in] byte_length: 作成する共有配列バッファの長さ(バイト単位)。
  • [out] data: SharedArrayBuffer の基底となるバイトバッファへのポインタ。dataNULL を渡すことで任意に無視できます。
  • [out] result: JavaScriptの SharedArrayBuffer を表す napi_value

API が成功した場合は napi_ok を返します。

このAPIは、JavaScriptの SharedArrayBuffer に対応するNode-APIの値を返します。SharedArrayBuffer は、複数のワーカー間で共有できる固定長のバイナリデータバッファを表すために使用されます。

割り当てられる SharedArrayBuffer は、渡された byte_length パラメータによってサイズが決定される基底のバイトバッファを持ちます。呼び出し元がバッファを直接操作したい場合に備えて、基底バッファはオプションで呼び出し元に返されます。このバッファは、ネイティブコードからのみ直接書き込むことができます。JavaScriptからこのバッファに書き込むには、型付き配列または DataView オブジェクトを作成する必要があります。

JavaScriptの SharedArrayBuffer オブジェクトは、ECMAScript言語仕様のセクション SharedArrayBuffer オブジェクトに記載されています。

JavaScriptプロパティの操作#

Node-APIは、JavaScriptオブジェクトのプロパティを取得および設定するための一連のAPIを公開しています。

JavaScriptのプロパティは、キーと値のタプルとして表現されます。基本的に、Node-APIのすべてのプロパティキーは、以下のいずれかの形式で表現できます。

  • 名前付き: 単純なUTF8エンコード文字列
  • 整数インデックス付き: uint32_t で表現されるインデックス値
  • JavaScript値: これらはNode-APIで napi_value によって表現されます。これは stringnumber、または 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 を除き、これらはECMAScript言語仕様セクション プロパティ属性にリストされている属性に対応します。これらは、以下のビットフラグの1つまたは複数です。

  • napi_default: プロパティに明示的な属性は設定されません。デフォルトでは、プロパティは読み取り専用で、列挙不可、設定不可です。
  • napi_writable: プロパティは書き込み可能です。
  • napi_enumerable: プロパティは列挙可能です。
  • napi_configurable: ECMAScript言語仕様セクション プロパティ属性で定義されているように、プロパティは設定可能です。
  • napi_static: プロパティは、デフォルトのインスタンスプロパティとは対照的に、クラスの静的プロパティとして定義されます。これは napi_define_class によってのみ使用されます。napi_define_properties では無視されます。
  • napi_default_method: JSクラスのメソッドのように、プロパティは設定可能で書き込み可能ですが、列挙不可です。
  • napi_default_jsproperty: JavaScriptでの代入によって設定されたプロパティのように、プロパティは書き込み可能、列挙可能、設定可能です。
napi_property_descriptor#
typedef struct {
  // One of utf8name or name should be NULL.
  const char* utf8name;
  napi_value name;

  napi_callback method;
  napi_callback getter;
  napi_callback setter;
  napi_value value;

  napi_property_attributes attributes;
  void* data;
} napi_property_descriptor; 
  • utf8name: プロパティのキーを記述するオプションの文字列で、UTF8でエンコードされます。プロパティには utf8name または name のいずれかを提供する必要があります。
  • name: プロパティのキーとして使用されるJavaScriptの文字列またはシンボルを指すオプションの napi_value。プロパティには utf8name または name のいずれかを提供する必要があります。
  • value: プロパティがデータプロパティの場合に、プロパティのgetアクセスによって取得される値。これが渡された場合、gettersettermethod、および dataNULL に設定します(これらのメンバーは使用されないため)。
  • getter: プロパティのgetアクセスが実行されたときに呼び出される関数。これを渡す場合は、valuemethodNULL に設定してください(これらのメンバーは使用されないため)。指定された関数は、プロパティがJavaScriptコードからアクセスされたとき(またはNode-API呼び出しを使用してプロパティのgetが実行されたとき)にランタイムによって暗黙的に呼び出されます。napi_callback で詳細を説明します。
  • setter: プロパティのsetアクセスが実行されたときに呼び出される関数。これを渡す場合は、valuemethodNULL に設定してください(これらのメンバーは使用されないため)。指定された関数は、プロパティがJavaScriptコードから設定されたとき(またはNode-API呼び出しを使用してプロパティのsetが実行されたとき)にランタイムによって暗黙的に呼び出されます。napi_callback で詳細を説明します。
  • method: これを設定して、プロパティ記述子オブジェクトの value プロパティを method で表されるJavaScript関数にします。これを渡す場合は、valuegettersetterNULL に設定してください(これらのメンバーは使用されないため)。napi_callback で詳細を説明します。
  • attributes: 特定のプロパティに関連付けられた属性です。napi_property_attributes を参照してください。
  • data: この関数が呼び出された場合に methodgettersetter に渡されるコールバックデータです。

関数#

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 です。napi_get_array_lengthnapi_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_lengthnapi_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: プロパティの削除が成功したかどうか。resultNULL を渡すことで任意に無視できます。

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 に指定された名前の自身のプロパティがあるかどうかをチェックします。keystring または 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: 要素の削除が成功したかどうか。resultNULL を渡すことで任意に無視できます。

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 仕様の セクション DefineOwnProperty で説明) によって定義されるように、オブジェクトにプロパティを 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 とそのデータの両方を napi_add_finalizer に渡すことで、object に関連付けられ、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 関数とデータの両方を napi_add_finalizer に渡すことで、結果の JavaScript 関数(result パラメータで返される)に関連付けられ、関数がガベージコレクションされるたびに解放されます。

JavaScript の Function は、ECMAScript 言語仕様の セクション Function objects で説明されています。

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 配列の長さを指定し、実際の引数の数を受け取ります。argcNULL を渡すことで任意に無視できます。
  • [out] argv: 引数がコピーされる napi_value の C 配列です。提供された数よりも多くの引数がある場合、要求された数の引数のみがコピーされます。要求された数よりも少ない引数が提供された場合、argv の残りは undefined を表す napi_value 値で埋められます。argvNULL を渡すことで任意に無視できます。
  • [out] thisArg: 呼び出しの JavaScript this 引数を受け取ります。thisArgNULL を渡すことで任意に無視できます。
  • [out] data: コールバックのデータポインタを受け取ります。dataNULL を渡すことで任意に無視できます。

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: コンストラクタへの引数を表す JavaScript 値の配列 (napi_value) です。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 から呼び出すことができるようにします。

  1. napi_define_class API は、C++ クラスに対応するコンストラクタ、静的プロパティとメソッド、およびインスタンスプロパティとメソッドを持つ JavaScript クラスを定義します。
  2. JavaScript コードがコンストラクタを呼び出すと、コンストラクタコールバックは napi_wrap を使用して新しい C++ インスタンスを JavaScript オブジェクトでラップし、そのラッパーオブジェクトを返します。
  3. 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 に保持すると、queryHashRecords() に渡されるインスタンスが実際に正しい型であることを確認するために napi_instanceof() を使用できるため、役立ちます。

残念ながら、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++ クラスをラップする場合、napi_unwrap を使用して JavaScript オブジェクトインスタンス内に配置された C++ クラスインスタンスを取得した後、napi_static 属性なしのプロパティ記述子で与えられた静的関数から、C++ クラスの 非静的 なデータプロパティ、アクセサ、およびメソッドを呼び出すことができます。

C++ クラスをラップする場合、constructor を介して渡される C++ コンストラクタコールバックは、実際のクラスコンストラクタを呼び出し、次に新しい C++ インスタンスを JavaScript オブジェクトでラップし、そのラッパーオブジェクトを返すクラスの静的メソッドであるべきです。napi_wrap の詳細を参照してください。

napi_define_class から返される JavaScript コンストラクタ関数は、多くの場合、保存され、後でネイティブコードからクラスの新しいインスタンスを構築するため、および/または提供された値がクラスのインスタンスであるかどうかを確認するために使用されます。その場合、関数値がガベージコレクションされるのを防ぐために、napi_create_reference を使用してそれに強い永続参照を作成し、参照カウントが 1 以上に保たれるようにします。

data パラメータまたは napi_property_descriptor 配列アイテムの data フィールドを介してこの API に渡される NULL 以外のデータは、JavaScript 関数とデータの両方を napi_add_finalizer に渡すことで、結果の JavaScript コンストラクタ(result パラメータで返される)に関連付けられ、クラスがガベージコレクションされるたびに解放されます。

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() を使用する場合、空の結果を処理する必要があります。

オブジェクトに対して 2 回目に napi_wrap() を呼び出すとエラーが返されます。別のネイティブインスタンスをオブジェクトに関連付けるには、まず 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 オブジェクトまたは external です。
  • [in] type_tag: オブジェクトをマークするタグです。

API が成功した場合は napi_ok を返します。

type_tag ポインタの値を JavaScript オブジェクトまたは external に関連付けます。その後、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 オブジェクトまたは external です。
  • [in] type_tag: オブジェクト上で見つかったタグと比較するタグです。
  • [out] result: 指定された型タグがオブジェクトの型タグと一致したかどうか。オブジェクトに型タグが見つからなかった場合も false が返されます。

API が成功した場合は napi_ok を返します。

type_tagとして与えられたポインタを、js_object上で見つかる可能性のあるものと比較します。js_object上でタグが見つからない場合、またはタグは見つかったがtype_tagと一致しない場合、resultfalseに設定されます。タグが見つかり、それがtype_tagと一致する場合、resulttrueに設定されます。

napi_add_finalizer#

napi_status napi_add_finalizer(napi_env env,
                               napi_value js_object,
                               void* finalize_data,
                               node_api_basic_finalize finalize_cb,
                               void* finalize_hint,
                               napi_ref* result); 
  • [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 は、単一の JavaScript オブジェクトに対して複数回呼び出すことができます。

注意: オプションで返される参照(取得された場合)は、ファイナライズコールバックの呼び出しに応じて napi_delete_reference を介してのみ削除されるべきです。それより前に削除されると、ファイナライズコールバックが呼び出されない可能性があります。したがって、参照を取得する際には、参照を正しく破棄できるようにするためにファイナライズコールバックも必要です。

node_api_post_finalizer#

安定性: 1 - Experimental

napi_status node_api_post_finalizer(node_api_basic_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 は、アドオンがそのような Node-API の呼び出しを GC のファイナライズ以外の時点まで延期できるようにすることで、この制限を回避するのに役立ちます。

単純な非同期操作#

アドオンモジュールは、実装の一部として libuv からの非同期ヘルパーを活用する必要がしばしばあります。これにより、作業が完了する前にメソッドが戻るように、非同期に実行される作業をスケジュールできます。これにより、Node.js アプリケーションの全体的な実行をブロックすることを回避できます。

Node-API は、最も一般的な非同期ユースケースをカバーするこれらのサポート関数のための ABI 安定インターフェースを提供します。

Node-API は、非同期ワーカーを管理するために使用される napi_async_work 構造体を定義します。インスタンスは napi_create_async_worknapi_delete_async_work で作成/削除されます。

executecomplete コールバックは、エグゼキュータが実行準備ができたときと、タスクを完了したときにそれぞれ呼び出される関数です。

execute 関数は、JavaScript の実行や JavaScript オブジェクトとの相互作用を引き起こす可能性のある Node-API 呼び出しを避けるべきです。ほとんどの場合、Node-API 呼び出しを行う必要があるコードは、代わりに complete コールバックで行うべきです。execute コールバックで napi_env パラメータを使用することは避けてください。JavaScript を実行する可能性が高いためです。

これらの関数は以下のインターフェースを実装します

typedef void (*napi_async_execute_callback)(napi_env env,
                                            void* data);
typedef void (*napi_async_complete_callback)(napi_env env,
                                             napi_status status,
                                             void* data); 

これらのメソッドが呼び出されると、渡される data パラメータは、napi_create_async_work 呼び出しに渡されたアドオン提供の void* データになります。

一度作成されると、非同期ワーカーは napi_queue_async_work 関数を使用して実行のためにキューに入れることができます

napi_status napi_queue_async_work(node_api_basic_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_hooksinit フックに渡されます。
  • [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_basic_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_basic_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_hooksinit フックに渡され、async_hooks.executionAsyncResource() によってアクセスできます。
  • [in] async_resource_name: async_hooks API によって公開される診断情報のために提供されているリソースの種類を示す識別子です。
  • [out] result: 初期化された非同期コンテキストです。

API が成功した場合は napi_ok を返します。

以前のバージョンとの ABI 互換性を維持するために、async_resourceNULL を渡してもエラーにはなりません。しかし、これは async_hooksinit フックasync_hooks.executionAsyncResource() で望ましくない動作を引き起こすため、推奨されません。なぜなら、リソースは非同期コールバック間の連携を提供するために、基礎となる async_hooks 実装によって要求されるからです。

この API の以前のバージョンでは、napi_async_context オブジェクトが存在する間、async_resource への強い参照を維持せず、代わりに呼び出し元が強い参照を保持することを期待していました。これは変更されました。なぜなら、メモリリークを避けるために、napi_async_init() の各呼び出しに対応する napi_async_destroy の呼び出しがいずれにせよ必須だからです。

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_contextNULL を渡してもエラーにはなりません。しかし、これにより非同期フックの動作が不正になります。潜在的な問題には、AsyncLocalStorage API を使用する際の非同期コンテキストの喪失が含まれます。
  • [in] recv: 呼び出された関数に渡される this の値です。
  • [in] func: 呼び出される JavaScript 関数を表す napi_value です。
  • [in] argc: argv 配列内の要素の数です。
  • [in] argv: 関数への引数を表す JavaScript 値 (napi_value) の配列です。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_make_callback 関数の使用は、napi_create_async_work を使用しないカスタム非同期動作を実装する場合に必要になることがあります。

コールバック中に 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_hooksinit フックに渡されます。このパラメータは非推奨となり、ランタイムで無視されます。napi_async_initasync_resource パラメータを代わりに使用してください。
  • [in] context: コールバックを呼び出す非同期操作のコンテキストです。これは、以前に napi_async_init から取得した値であるべきです。
  • [out] result: 新しく作成されたスコープです。

特定の Node-API 呼び出しを行う際に、コールバックに関連付けられたスコープと同等のものが必要な場合があります(例えば、Promise を解決する場合など)。スタック上に他のスクリプトがない場合、napi_open_callback_scopenapi_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_basic_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_basic_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_basic_env env,
                                                    int64_t change_in_bytes,
                                                    int64_t* result); 
  • [in] env: API が呼び出される環境。
  • [in] change_in_bytes: JavaScript オブジェクトによって維持される外部で割り当てられたメモリの変化量です。
  • [out] result: 調整された値です。この値は、指定された change_in_bytes を含んだ外部メモリの総量を反映する必要があります。返される値の絶対値に依存すべきではありません。例えば、実装はすべてのアドオンに対して単一のカウンタを使用することも、各アドオンに対してカウンタを使用することもあります。

API が成功した場合は napi_ok を返します。

この関数は、JavaScript オブジェクトによって維持される外部で割り当てられたメモリの量をランタイムに示します(つまり、ネイティブアドオンによって割り当てられた自身のメモリを指す JavaScript オブジェクト)。外部で割り当てられたメモリを登録すると、グローバルなガベージコレクションが通常よりも頻繁にトリガーされる可能性がありますが、保証はされません。

この関数は、アドオンが外部メモリを増加させた量よりも多く減少させないような方法で呼び出されることが期待されます。

Promise#

Node-API は、ECMA 仕様の セクション Promise オブジェクトで説明されている Promise オブジェクトを作成するための機能を提供します。これは、Promise をオブジェクトのペアとして実装します。napi_create_promise() によって Promise が作成されると、「deferred」オブジェクトが作成され、Promise と一緒に返されます。deferred オブジェクトは作成された Promise にバインドされ、napi_resolve_deferred() または napi_reject_deferred() を使用して Promise を解決または拒否する唯一の手段です。napi_create_promise() によって作成された deferred オブジェクトは、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() は、非同期アクションを実行し、その後、deferred を解決または拒否し、それによって Promise を完了させ、deferred を解放します

napi_deferred deferred;
napi_value undefined;
napi_status status;

// Create a value with which to conclude the deferred.
status = napi_get_undefined(env, &undefined);
if (status != napi_ok) return NULL;

// Resolve or reject the promise associated with the deferred depending on
// whether the asynchronous action succeeded.
if (asynchronous_action_succeeded) {
  status = napi_resolve_deferred(env, deferred, undefined);
} else {
  status = napi_reject_deferred(env, deferred, undefined);
}
if (status != napi_ok) return NULL;

// At this point the deferred has been freed, so we should assign NULL to it.
deferred = NULL; 

napi_create_promise#

napi_status napi_create_promise(napi_env env,
                                napi_deferred* deferred,
                                napi_value* promise); 
  • [in] env: API が呼び出される環境。
  • [out] deferred: 新しく作成された deferred オブジェクトで、後で napi_resolve_deferred() または napi_reject_deferred() に渡して、関連付けられた Promise をそれぞれ解決または拒否できます。
  • [out] promise: deferred オブジェクトに関連付けられた JavaScript Promise です。

API が成功した場合は napi_ok を返します。

この API は、deferred オブジェクトと 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 を解決する deferred オブジェクトです。
  • [in] resolution: Promise を解決する値です。

この API は、JavaScript Promise をそれに関連付けられた deferred オブジェクトを介して解決します。したがって、対応する deferred オブジェクトが利用可能な JavaScript Promise を解決するためにのみ使用できます。これは、実質的に、Promise が napi_create_promise() を使用して作成され、その呼び出しから返された deferred オブジェクトがこの API に渡されるために保持されている必要があることを意味します。

deferred オブジェクトは、正常に完了すると解放されます。

napi_reject_deferred#

napi_status napi_reject_deferred(napi_env env,
                                 napi_deferred deferred,
                                 napi_value rejection); 
  • [in] env: API が呼び出される環境。
  • [in] deferred: 関連付けられた Promise を解決する deferred オブジェクトです。
  • [in] rejection: Promise を拒否する値です。

この API は、JavaScript Promise をそれに関連付けられた deferred オブジェクトを介して拒否します。したがって、対応する deferred オブジェクトが利用可能な JavaScript Promise を拒否するためにのみ使用できます。これは、実質的に、Promise が napi_create_promise() を使用して作成され、その呼び出しから返された deferred オブジェクトがこの API に渡されるために保持されている必要があることを意味します。

deferred オブジェクトは、正常に完了すると解放されます。

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 コードの文字列を実行し、その結果を以下の注意点とともに返します

  • eval とは異なり、この関数はスクリプトが現在のレキシカルスコープにアクセスすることを許可せず、したがって モジュールスコープにアクセスすることも許可しません。つまり、require のような疑似グローバルは利用できません。
  • スクリプトは グローバルスコープにアクセスできます。スクリプト内の関数と var 宣言は global オブジェクトに追加されます。letconst を使用して行われた変数宣言はグローバルに表示されますが、global オブジェクトには追加されません。
  • this の値は、スクリプト内では global です。

libuv イベントループ#

Node-API は、特定の napi_env に関連付けられた現在のイベントループを取得するための関数を提供します。

napi_get_uv_event_loop#

NAPI_EXTERN napi_status napi_get_uv_event_loop(node_api_basic_env env,
                                               struct uv_loop_s** loop); 
  • [in] env: API が呼び出される環境。
  • [out] loop: 現在の libuv ループインスタンスです。

注意: libuv は時間とともに比較的安定していますが、ABI の安定性は保証されていません。この関数の使用は避けるべきです。その使用は、Node.js のバージョン間で動作しないアドオンになる可能性があります。多くのユースケースでは、非同期スレッドセーフ関数呼び出しが代替手段となります。

非同期スレッドセーフ関数呼び出し#

JavaScript 関数は通常、ネイティブアドオンのメインスレッドからのみ呼び出すことができます。アドオンが追加のスレッドを作成する場合、napi_envnapi_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 スレッドから napi_tsfn_blocking で呼び出すべきではありません。なぜなら、キューが満杯の場合、JavaScript スレッドがデッドロックする可能性があるからです。

実際の JavaScript への呼び出しは、call_js_cb パラメータを介して与えられるコールバックによって制御されます。call_js_cb は、napi_call_threadsafe_function() への成功した呼び出しによってキューに置かれた各値に対して一度、メインスレッドで呼び出されます。そのようなコールバックが与えられない場合、デフォルトのコールバックが使用され、結果の JavaScript 呼び出しには引数がありません。call_js_cb コールバックは、呼び出す JavaScript 関数をパラメータとして napi_value で受け取ります。また、napi_threadsafe_function の作成時に使用された void* コンテキストポインタと、セカンダリスレッドの 1 つによって作成された次のデータポインタも受け取ります。コールバックは、napi_call_function() などの API を使用して JavaScript を呼び出すことができます。

コールバックは、envcall_js_cb の両方が NULL に設定されて呼び出されることもあります。これは、JavaScript への呼び出しがもはや不可能であることを示し、キューには解放が必要なアイテムが残っている可能性があります。これは通常、スレッドセーフ関数がまだアクティブな状態で Node.js プロセスが終了するときに発生します。

Node-API は call_js_cb をコールバックに適したコンテキストで実行するため、napi_make_callback() を介して JavaScript を呼び出す必要はありません。

イベントループの各ティックで、0 個以上のキューに入れられたアイテムが呼び出される場合があります。アプリケーションは、コールバックの呼び出しが進み、時間が進むにつれてイベントが呼び出されるという特定の動作以外に依存すべきではありません。

スレッドセーフ関数の参照カウント#

スレッドは、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() を呼び出してそれを使用し始めることができるスレッドはなくなります。実際、それに関連する後続のすべての API 呼び出しは、napi_release_threadsafe_function() を除き、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_functionnapi_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_cbNULL が渡された場合は提供する必要があります。
  • [in] async_resource: 非同期作業に関連付けられたオプションのオブジェクトで、可能性のある async_hooksinit フックに渡されます。
  • [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 関数です。

変更履歴

  • バージョン10(NAPI_VERSION10 以上として定義されている場合)

    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_tsfn_nonblocking (キューが満杯の場合に呼び出しがすぐに napi_queue_full のステータスで返されることを示す) のいずれかであるフラグです。

この API は、JavaScript スレッドから napi_tsfn_blocking で呼び出すべきではありません。なぜなら、キューが満杯の場合、JavaScript スレッドがデッドロックする可能性があるからです。

この API は、任意のスレッドから abortnapi_tsfn_abort に設定して napi_release_threadsafe_function() が呼び出された場合、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 の使用を停止したときに 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_basic_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_functionnapi_release_threadsafe_function が利用可能です。

この API は、メインスレッドからのみ呼び出すことができます。

napi_unref_threadsafe_function#

NAPI_EXTERN napi_status
napi_unref_threadsafe_function(node_api_basic_env env, napi_threadsafe_function func); 
  • [in] env: API が呼び出される環境。
  • [in] func: 参照を解除するスレッドセーフ関数です。

この API は、メインスレッドで実行されているイベントループが、func が破棄される前に終了する可能性があることを示すために使用されます。uv_unref と同様に、これも冪等です。

この API は、メインスレッドからのみ呼び出すことができます。

その他のユーティリティ#

node_api_get_module_file_name#

NAPI_EXTERN napi_status
node_api_get_module_file_name(node_api_basic_env env, const char** result);
 
  • [in] env: API が呼び出される環境。
  • [out] result: アドオンがロードされた場所の絶対パスを含む URL です。ローカルファイルシステムのファイルの場合、file:// で始まります。文字列は null 終端で env によって所有されており、したがって変更または解放してはなりません。

アドオンの読み込みプロセスが読み込み中にアドオンのファイル名を確立できなかった場合、result は空の文字列になることがあります。