使用Node-API接口进行生命周期相关开发
======================

#### 简介

在Node-API中，napi\_value是一个表示ArkTS值的抽象类型，它可以表示任何ArkTS值，包括基本类型（如数字、字符串、布尔值）和复杂对象类型（如数组、函数、对象等）。

napi\_value的生命周期与其在ArkTS中的对应值的生命周期紧密相关。当ArkTS值被垃圾回收时，与之关联的napi\_value也将不再有效。重要的是不要在ArkTS值不再存在时尝试使用napi\_value。

框架层的scope通常用于管理napi\_value的生命周期。在Node-API中，可以使用napi\_open\_handle\_scope和napi\_close\_handle\_scope函数来创建和销毁scope。通过在scope内创建napi\_value，可以确保在scope结束时自动释放napi\_value，避免内存泄漏。

napi\_ref是一个Node-API类型，用于管理napi\_value的生命周期。napi\_ref允许您在napi\_value的生命周期内保持对其的引用，即使它已经超出了其原始上下文的范围。这使得您可以在不同的上下文中共享napi\_value，并确保在不再需要时正确释放其内存。

#### 基本概念

Node-API提供了一组功能，使开发人员能够在Node-API模块中创建和操作ArkTS对象，管理引用和生命周期，并注册垃圾回收回调函数等。下面是一些基本概念：

*   **作用域**：用于管理ArkTS对象的生命周期。在某个作用域中创建的对象句柄，默认情况下只能在该作用域内使用。当作用域被关闭后，其中创建的对象将无法再被访问，除非显式地将它们逃逸出当前作用域。
*   **引用管理**：Node-API提供函数来创建、删除和管理对象的引用，以延长对象的生命周期，避免出现对象use-after-free的问题。同时也通过引用管理去避免发生内存泄漏的问题。
*   **可逃逸的作用域**：允许在创建的作用域中声明的对象返回到父作用域，通过napi\_open\_escapable\_handle\_scope和napi\_close\_escapable\_handle\_scope进行管理。
*   **垃圾回收回调**：允许注册回调函数，以便在ArkTS对象被垃圾回收时执行特定的清理操作。

这些基本概念使开发人员能够在Node-API模块中安全且有效地操作ArkTS对象，并确保正确管理对象的生命周期。

#### 场景和功能介绍

以下Node-API接口主要用于ArkTS对象的引用管理，并确保在Node-API模块代码中正确地处理ArkTS对象的生命周期。使用场景如下：

| 接口 | 描述 |
| :-- | :-- |
| napi\_open\_handle\_scope、napi\_close\_handle\_scope | 主要用于管理ArkTS对象的生命周期，确保在Node-API模块代码中使用ArkTS对象时能够正确地进行内存管理。当在Node-API模块中处理ArkTS对象时，需要创建一个临时的作用域来存储对象的引用，以便在执行期间正确访问这些对象，并在执行结束后关闭这个handle scope。 |
| napi\_open\_escapable\_handle\_scope、napi\_close\_escapable\_handle\_scope | 用于创建一个可逃逸的作用域，使得在原生函数中创建的ArkTS对象可以被正确返回到调用该函数的外部ArkTS环境中。 |
| napi\_escape\_handle | 将ArkTS对象的生命周期提升到父作用域中，避免对象被意外释放。 |
| napi\_create\_reference、napi\_delete\_reference | 主要用于在Node-API模块代码中管理ArkTS对象的引用，以确保对象的生命周期符合插件的需求。 |
| napi\_reference\_ref、napi\_reference\_unref | 主要用于管理ArkTS对象引用的引用计数，以确保在多个地方共享引用时引用计数能够正确地增加和减少。 |
| napi\_get\_reference\_value | 主要用于在Node-API模块代码中获取与引用相关联的ArkTS对象，以便在Node-API模块中对其进行操作。 |
| napi\_add\_finalizer | 在需要在ArkTS对象被垃圾回收前执行一些清理或释放资源的情况下，确保资源的正确释放和管理。 |

#### 使用示例

Node-API接口开发流程参考[使用Node-API实现跨语言交互开发流程](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/use-napi-process)，本文仅对接口对应C++及ArkTS相关代码进行展示。

本文cpp部分代码所需引用的头文件如下：

#include "napi/native\_api.h"
// log.h用于C++中日志打印
#include "hilog/log.h"

本文ArkTS侧示例代码所需的模块导入如下：

import { hilog } from '@kit.PerformanceAnalysisKit';
import testNapi from 'libentry.so';

#### \[h2\]napi\_open\_handle\_scope、napi\_close\_handle\_scope

通过接口napi\_open\_handle\_scope创建一个上下文环境，并使用napi\_close\_handle\_scope进行关闭。这组接口用于管理ArkTS对象的生命周期，确保在Node-API模块代码处理ArkTS对象时能够正确地管理其句柄，以避免出现对象错误回收的问题。

需要注意的是，接口仅支持单层嵌套的scope结构。在任何时刻，只有一个scope处于活动状态，所有新创建的handles都将与该scope相关联。scope必须按照与打开顺序相反的顺序关闭。此外，在native方法中创建的所有scope必须在该方法返回之前被关闭。

关于生命周期管理的代码部分也可参考下面链接：

[生命周期管理](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/napi-guidelines#生命周期管理)

关于典型错误使用方法的代码部分也可参考下面链接:

[典型错误场景](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/napi-faq-about-stability#napi_open_handle_scope与napi_close_handle_scope进行生命周期相关开发典型错误场景)

cpp部分代码

// napi\_open\_handle\_scope、napi\_close\_handle\_scope
static napi\_value HandleScopeTest(napi\_env env, napi\_callback\_info info)
{
    // 通过调用napi\_open\_handle\_scope来创建一个句柄作用域
    napi\_handle\_scope scope;
    napi\_open\_handle\_scope(env, &scope);
    // 在句柄作用域内创建一个obj
    napi\_value obj = nullptr;
    napi\_create\_object(env, &obj);
    // 在对象中添加属性
    napi\_value value = nullptr;
    napi\_create\_string\_utf8(env, "handleScope", NAPI\_AUTO\_LENGTH, &value);
    napi\_set\_named\_property(env, obj, "key", value);
    // 在作用域内获取obj的属性并返回
    napi\_value result = nullptr;
    napi\_get\_named\_property(env, obj, "key", &result);
    // 关闭句柄作用域，自动释放在该作用域内创建的对象句柄
    napi\_close\_handle\_scope(env, scope);
    // result已经离开scope的作用域，继续使用可能会存在稳定性问题，如果需要在作用域外使用对象，建议使用napi\_open\_escapable\_handle\_scope系列接口
    return nullptr;
}

static napi\_value HandleScope(napi\_env env, napi\_callback\_info info)
{
    // 通过调用napi\_open\_handle\_scope来创建一个句柄作用域
    napi\_handle\_scope scope;
    napi\_open\_handle\_scope(env, &scope);
    // 在句柄作用域内创建一个obj
    napi\_value obj = nullptr;
    napi\_create\_object(env, &obj);
    // 在对象中添加属性
    napi\_value value = nullptr;
    napi\_create\_string\_utf8(env, "handleScope", NAPI\_AUTO\_LENGTH, &value);
    napi\_set\_named\_property(env, obj, "key", value);
    // 关闭句柄作用域，自动释放在该作用域内创建的对象句柄
    napi\_close\_handle\_scope(env, scope);
    // 在作用域外获取obj的属性并返回，此处只能得到“undefined”
    napi\_value result = nullptr;
    napi\_get\_named\_property(env, obj, "key", &result);
    return result;
}

接口声明

index.d.ts

export const handleScopeTest: () => string; // napi\_open\_handle\_scope、napi\_close\_handle\_scope

export const handleScope: () => string;

ArkTS侧示例代码

// napi\_open\_handle\_scope  napi\_close\_handle\_scope
try {
  hilog.info(0x0000, 'testTag', 'Test Node-API handleScopeTest: %{public}s',
    testNapi.handleScopeTest());
  hilog.info(0x0000, 'testTag', 'Test Node-API handleScope: %{public}s', testNapi.handleScope());
  // ...
} catch (error) {
  hilog.error(0x0000, 'testTag',
    'Test Node-API handleScopeTest errorCode: %{public}s, errorMessage: %{public}s', error.code,
    error.message);
  // ...
}

框架层在核心初始化函数Init中定义了ArkTS侧和native侧的接口映射表，在ArkTS侧通过映射表中的接口访问native侧的函数时，框架层会自动加上scope, 不需要额外增加napi\_open\_handle\_scope、napi\_close\_handle\_scope接口来管理ArkTS对象的生命周期。即：进入开发者自己写的native函数前自动open scope, native函数结束后自动close scope。native侧函数中创建的ArkTS对象的生命周期在native函数返回时结束，不会存在内存泄漏的问题。以NewObject函数举例如下（定义接口映射表中映射的函数不需要手动加napi\_open\_handle\_scope、napi\_close\_handle\_scope管理ArkTS对象的生命周期）：

// 调用NewObject前会open scope
napi\_value NewObject(napi\_env env, napi\_callback\_info info)
{
    napi\_value object = nullptr;
    // 创建一个空对象
    napi\_create\_object(env, &object);
    // 设置对象的属性
    napi\_value name = nullptr;
    // 设置属性名为"name"
    napi\_create\_string\_utf8(env, "name", NAPI\_AUTO\_LENGTH, &name);
    napi\_value value = nullptr;
    // 设置属性值为"Hello from Node-API!"
    napi\_create\_string\_utf8(env, "Hello from Node-API!", NAPI\_AUTO\_LENGTH, &value);
    // 将属性设置到对象上
    napi\_set\_property(env, object, name, value);
    //result离开作用域后，对象句柄（handle）跟随释放，返回到ArkTS侧的对象由ArkTS侧管理
    return object;
}
// NewObject调用函数结束后框架层会close scope

// 核心初始化函数
static napi\_value Init(napi\_env env, napi\_value exports)
{
    // 定义接口映射表
    napi\_property\_descriptor desc\[\] = {
        { "newObject", nullptr, NewObject, nullptr, nullptr, nullptr, napi\_default, nullptr }
    };
    napi\_define\_properties(env, exports, sizeof(desc) / sizeof(desc\[0\]), desc);
    return exports;
}

#### \[h2\]napi\_open\_escapable\_handle\_scope、napi\_close\_escapable\_handle\_scope、napi\_escape\_handle

通过接口napi\_open\_escapable\_handle\_scope创建出一个可逃逸的handle scope，可将范围内声明的值返回到父作用域。该作用域需要使用napi\_close\_escapable\_handle\_scope进行关闭。napi\_escape\_handle用于提升传入的ArkTS对象的生命周期到其父作用域。

通过上述接口可以更灵活的使用管理传入的ArkTS对象，特别是在处理跨作用域的值传递时非常有用。

cpp部分代码

// napi\_open\_escapable\_handle\_scope、napi\_close\_escapable\_handle\_scope、napi\_escape\_handle
static napi\_value EscapableHandleScopeTest(napi\_env env, napi\_callback\_info info)
{
    // 创建一个可逃逸的句柄作用域
    napi\_escapable\_handle\_scope scope;
    napi\_open\_escapable\_handle\_scope(env, &scope);
    // 在可逃逸的句柄作用域内创建一个obj
    napi\_value obj = nullptr;
    napi\_create\_object(env, &obj);
    // 在对象中添加属性
    napi\_value value = nullptr;
    napi\_create\_string\_utf8(env, "Test napi\_escapable\_handle\_scope", NAPI\_AUTO\_LENGTH, &value);
    napi\_set\_named\_property(env, obj, "key", value);
    napi\_value prop = nullptr;
    napi\_get\_named\_property(env, obj, "key", &prop);
    // 调用napi\_escape\_handle将属性值逃逸到作用域之外
    napi\_value result = nullptr;
    napi\_escape\_handle(env, scope, prop, &result);
    // 关闭可逃逸的句柄作用域，清理资源
    napi\_close\_escapable\_handle\_scope(env, scope);
    // 逃逸后的result可以在作用域外继续使用
    return result;
}

接口声明

index.d.ts

export const escapableHandleScopeTest: () => string; // napi\_open\_escapable\_handle\_scope、napi\_close\_escapable\_handle\_scope、napi\_escape\_handle

ArkTS侧示例代码

// napi\_open\_escapable\_handle\_scope napi\_close\_escapable\_handle\_scope、napi\_escape\_handle
try {
  hilog.info(0x0000, 'testTag', 'Test Node-API EscapableHandleScopeTest: %{public}s',
    testNapi.escapableHandleScopeTest());
  // ...
} catch (error) {
  hilog.error(0x0000, 'testTag',
    'Test Node-API EscapableHandleScopeTest errorCode: %{public}s, errorMessage: %{public}s',
    error.code,
    error.message);
  // ...
}

#### \[h2\]napi\_ref

napi\_ref 是 napi 中用于管理 ArkTS 对象生命周期的引用类型，分为强引用和弱引用两种类型。当ref计数为0时为弱引用，计数大于0时为强引用。强引用会阻止垃圾回收器回收被引用的对象，适用于需要长期保持对象存活的场景，但必须手动管理引用计数和释放，否则会导致内存泄漏；弱引用则不会阻止垃圾回收，允许对象在不再被其他强引用持有时被正常回收，适用于缓存等临时性引用场景，能够自动失效但需要在获取时检查对象是否仍存活。正确选择强弱引用类型对于平衡内存管理和性能至关重要。

#### \[h2\]napi\_create\_reference、napi\_delete\_reference

为Object创建一个reference，以延长其生命周期。调用者需要自己管理reference生命周期。可以调用napi\_delete\_reference删除传入的reference。

#### \[h2\]napi\_reference\_ref、napi\_reference\_unref

增加/减少传入的reference的引用计数，并获取新的计数。

#### \[h2\]napi\_get\_reference\_value

获取与reference相关联的ArkTS Object。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/b0/v3/ip3gEuNAQjmfsKtuckwaBw/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132816Z&HW-CC-Expire=86400&HW-CC-Sign=C7C56C8CC606BD0DA35391CAF7132B46F16F0856ADA7A5C8878F71AF6F40E020)

由于弱引用（引用计数为0的napi\_ref）的释放与gc回收js对象并非同时发生。

因此可能在弱引用被释放前，js对象已经被回收。

这意味着你可能在napi\_ref有效的情况下，通过本接口获取到一个空指针。

**弱引用使用示例代码：**

创建时将引用计数初始化为0，这样创建的ref即为弱引用，弱引用不会阻止对象被回收。获取前需将weakValue初始化为nullptr，获取后检查weakValue是否仍为nullptr。若为nullptr，说明对象已被回收；若不为nullptr，则可继续使用。

cpp部分代码

#include "napi/native\_api.h"

napi\_ref g\_weakRef = nullptr;

static napi\_value CreateWeakReference(napi\_env env, napi\_callback\_info info)
{
    napi\_value value = nullptr;
    napi\_create\_string\_utf8(env, "This is a test property", NAPI\_AUTO\_LENGTH, &value);
    napi\_value jsObject = nullptr;
    napi\_create\_object(env, &jsObject);
    napi\_set\_named\_property(env, jsObject, "test", value);

    // 清理之前的引用（如果存在）
    if (g\_weakRef != nullptr) {
        napi\_delete\_reference(env, g\_weakRef);
        g\_weakRef = nullptr;
    }

    // 创建弱引用，不会阻止垃圾回收，没有其他强引用持有时会被正常回收
    napi\_status status = napi\_create\_reference(env, jsObject, 0, &g\_weakRef);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "Failed to create weak reference");
        return nullptr;
    }

    return nullptr;
}

static napi\_value GetWeakReferenceValue(napi\_env env, napi\_callback\_info info)
{
    napi\_value weakValue;
    napi\_status status = napi\_get\_reference\_value(env, g\_weakRef, &weakValue);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "Failed to get reference value");
        return nullptr;
    }

    // 判断对象是否已被回收
    if (weakValue == nullptr) {
        napi\_throw\_error(env, nullptr, "Object has been garbage collected");
        return nullptr;
    }

    // 尝试获取对象的属性来确认它仍然有效
    napi\_value result = nullptr;
    napi\_get\_named\_property(env, weakValue, "test", &result);

    return result;
}

接口声明

// index.d.ts

export const createWeakReference: () => void;

export const getWeakReferenceValue: () => string;

ArkTS侧示例代码

try {
    testNapi.createWeakReference();
    hilog.info(0x0000, 'testTag', 'reference test: %{public}s', testNapi.getWeakReferenceValue());
} catch (error) {
    hilog.error(0x0000, 'testTag', \`调用错误：${error.message}\`);
}

**强引用使用示例代码：**

创建时将引用计数初始化为1，这样创建的ref即为强引用，保证对象不会被回收。不再使用时调用napi\_delete\_reference释放对象，避免内存泄漏。

cpp部分代码

#include "napi/native\_api.h"

// 全局强引用
napi\_ref g\_strongRef = nullptr;

// 创建强引用
static napi\_value CreateStrongReference(napi\_env env, napi\_callback\_info info)
{
    napi\_value value = nullptr;
    napi\_create\_string\_utf8(env, "This is a test property", NAPI\_AUTO\_LENGTH, &value);
    napi\_value jsObject = nullptr;
    napi\_create\_object(env, &jsObject);
    napi\_set\_named\_property(env, jsObject, "test", value);

    // 清理之前的强引用（如果存在）
    if (g\_strongRef != nullptr) {
        napi\_delete\_reference(env, g\_strongRef);
        g\_strongRef = nullptr;
    }

    // 创建强引用（初始引用计数为1），阻止垃圾回收器回收
    napi\_status status = napi\_create\_reference(env, jsObject, 1, &g\_strongRef);

    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "Failed to create strong reference");
        return nullptr;
    }

    return nullptr;
}

static napi\_value GetStrongReferenceValue(napi\_env env, napi\_callback\_info info)
{
    napi\_value jsValue;
    napi\_status status = napi\_get\_reference\_value(env, g\_strongRef, &jsValue);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "Failed to get reference value");
        return nullptr;
    }

    // 尝试获取对象的属性来确认它仍然有效
    napi\_value result = nullptr;
    napi\_get\_named\_property(env, jsValue, "test", &result);

    return result;
}

// 清理强引用
static napi\_value CleanupStrongReference(napi\_env env, napi\_callback\_info info) {
    napi\_value ret = nullptr;
    if (g\_strongRef != nullptr) {
        // 强制删除引用，即使引用计数不为0
        napi\_delete\_reference(env, g\_strongRef);
        g\_strongRef = nullptr;
        napi\_get\_boolean(env, true, &ret);
        return ret;
    }
    napi\_get\_boolean(env, false, &ret);
    return ret;
}

接口声明

// index.d.ts

export const createStrongReference: () => void;

export const getStrongReferenceValue: () => string;

export const cleanupStrongReference: () => void;

ArkTS侧示例代码

try {
    testNapi.createStrongReference();
    hilog.info(0x0000, 'testTag', 'reference test: %{public}s', testNapi.getStrongReferenceValue());
    testNapi.cleanupStrongReference();
} catch (error) {
    hilog.error(0x0000, 'testTag', \`调用错误：${error.message}\`);
}

#### \[h2\]napi\_add\_finalizer

当ArkTS Object中的对象被垃圾回收时调用注册的napi\_add\_finalizer回调。

cpp部分代码

// 创建一个napi\_ref类型的指针，用于存储创建的引用。在调用napi\_add\_finalizer函数前，分配一个napi\_ref类型的变量，并传递其地址作为result参数。
napi\_ref gRefFinalizer = nullptr;

// 创建一个napi\_ref类型的指针，用于存储创建的引用。在调用napi\_create\_reference函数前，分配一个napi\_ref类型的变量，并传递其地址作为result参数。
napi\_ref gRef = nullptr;

void Finalizer(napi\_env env, void \*data, void \*hint)
{
    // 执行资源清理操作
    OH\_LOG\_INFO(LOG\_APP, "Test Node-API Use Finalizer to release resources.");
    // do something 执行资源清理操作
}

static napi\_value AddFinalizer(napi\_env env, napi\_callback\_info info)
{
    napi\_value obj = nullptr;
    napi\_status status = napi\_create\_object(env, &obj);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "napi\_create\_object fail");
        return nullptr;
    }
    napi\_value value = nullptr;
    status = napi\_create\_string\_utf8(env, "AddFinalizer", NAPI\_AUTO\_LENGTH, &value);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "napi\_create\_string\_utf8 fail");
        return nullptr;
    }
    // 将键值对添加到对象中
    status = napi\_set\_named\_property(env, obj, "key", value);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "napi\_set\_named\_property fail");
        return nullptr;
    }

    // 注册回调函数Finalizer用于清理资源
    void \*data = {};
    status = napi\_add\_finalizer(env, obj, data, Finalizer, nullptr, &gRefFinalizer);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "napi\_add\_finalizer fail");
        return nullptr;
    }

    return obj;
}

static napi\_value CreateReference(napi\_env env, napi\_callback\_info info)
{
    napi\_value obj = nullptr;
    napi\_status status = napi\_create\_object(env, &obj);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "napi\_create\_object fail");
        return nullptr;
    }
    napi\_value value = nullptr;
    status = napi\_create\_string\_utf8(env, "CreateReference", NAPI\_AUTO\_LENGTH, &value);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "napi\_create\_string\_utf8 fail");
        return nullptr;
    }
    // 将键值对添加到对象中
    status = napi\_set\_named\_property(env, obj, "key", value);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "napi\_set\_named\_property fail");
        return nullptr;
    }
    // 创建对ArkTS对象的引用
    status = napi\_create\_reference(env, obj, 1, &gRef);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "napi\_create\_reference fail");
        return nullptr;
    }
    // 增加传入引用的引用计数并返回生成的引用计数
    uint32\_t result = 0;
    status = napi\_reference\_ref(env, gRef, &result);
    OH\_LOG\_INFO(LOG\_APP, "Test Node-API napi\_reference\_ref, count = %{public}d.", result);
    uint32\_t numCount = 2;
    if (status != napi\_ok || result != numCount) {
        // 若传入引用的引用计数未增加，则抛出错误
        napi\_throw\_error(env, nullptr, "napi\_reference\_ref fail");
        return nullptr;
    }
    return obj;
}

static napi\_value UseReference(napi\_env env, napi\_callback\_info info)
{
    napi\_value obj = nullptr;
    // 通过调用napi\_get\_reference\_value获取引用的ArkTS对象
    napi\_status status = napi\_get\_reference\_value(env, gRef, &obj);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "napi\_get\_reference\_value fail");
        return nullptr;
    }
    // 返回获取的对象
    return obj;
}

static napi\_value DeleteReference(napi\_env env, napi\_callback\_info info)
{
    // 减少传入引用的引用计数并返回生成的引用计数
    uint32\_t result = 0;
    napi\_value count = nullptr;
    napi\_status status = napi\_reference\_unref(env, gRef, &result);
    OH\_LOG\_INFO(LOG\_APP, "Test Node-API napi\_reference\_unref, count = %{public}d.", result);
    uint32\_t numCount = 1;
    if (status != napi\_ok || result != numCount) {
        // 若传入引用的引用计数未减少，则抛出错误
        napi\_throw\_error(env, nullptr, "napi\_reference\_unref fail");
        return nullptr;
    }

    // 通过调用napi\_delete\_reference删除对ArkTS对象的引用
    status = napi\_delete\_reference(env, gRef);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "napi\_delete\_reference fail");
        return nullptr;
    }

    status = napi\_delete\_reference(env, gRefFinalizer);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "napi\_delete\_reference fail");
        return nullptr;
    }
    napi\_value returnResult = nullptr;
    status = napi\_create\_string\_utf8(env, "napi\_delete\_reference success", NAPI\_AUTO\_LENGTH, &returnResult);
    if (status != napi\_ok) {
        napi\_throw\_error(env, nullptr, "napi\_create\_string\_utf8 fail");
        return nullptr;
    }
    return returnResult;
}

接口声明

// index.d.ts

export const addFinalizer: () => Object | undefined; // napi\_add\_finalizer

export const createReference: () => Object | undefined; // napi\_create\_reference、napi\_reference\_ref

export const useReference: () => Object | undefined; // napi\_get\_reference\_value

export const deleteReference: () => string | undefined; // napi\_delete\_reference、napi\_reference\_unref

ArkTS侧示例代码

// napi\_add\_finalizer
try {
  hilog.info(0x0000, 'testTag', 'Test Node-API addFinalizer: %{public}s',
    JSON.stringify(testNapi.addFinalizer()));
  hilog.info(0x0000, 'testTag', 'Test Node-API createReference: %{public}s',
    JSON.stringify(testNapi.createReference()));
  hilog.info(0x0000, 'testTag', 'Test Node-API useReference: %{public}s',
    JSON.stringify(testNapi.useReference()));
  hilog.info(0x0000, 'testTag', 'Test Node-API deleteReference: %{public}s',
    testNapi.deleteReference());
  // ...
} catch (error) {
  hilog.error(0x0000, 'testTag',
    'Test Node-API ReferenceTest errorCode: %{public}s, errorMessage: %{public}s', error.code,
    error.message);
  // ...
}

以上代码如果要在native cpp中打印日志，需在CMakeLists.txt文件中添加以下配置信息（并添加头文件：#include "hilog/log.h"）：

// CMakeLists.txt
add\_definitions( "-DLOG\_DOMAIN=0xd0d0" )
add\_definitions( "-DLOG\_TAG=\\"testTag\\"" )
target\_link\_libraries(entry PUBLIC libace\_napi.z.so libhilog\_ndk.z.so)