使用Node-API进行扩展能力功能开发
====================

#### 简介

[扩展能力](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/napi-data-types-interfaces#扩展能力)接口进一步扩展了Node-API的功能，提供了一些额外的接口，用于在Node-API模块中与ArkTS进行更灵活的交互和定制，这些接口可以用于创建自定义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"
#include <bits/alltypes.h>
#include <mutex>
#include <unordered\_set>
#include <uv.h>
#include "hilog/log.h"

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

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

#### 模块加载

#### \[h2\]接口描述

| 接口 | 描述 |
| :-- | :-- |
| napi\_load\_module | 用于在Node-API模块中将abc文件作为模块加载，返回模块的命名空间，适用于需要在运行时动态加载模块或资源的应用程序，从而实现灵活的扩展和定制。 |
| napi\_load\_module\_with\_info | 用于在Node-API中进行模块的加载，当模块加载出来之后，可以使用函数napi\_get\_property获取模块导出的变量，也可以使用napi\_get\_named\_property获取模块导出的函数，该函数可以在[新创建的ArkTS基础运行时环境](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/use-napi-ark-runtime)中使用。 |
| napi\_module\_register | 有些功能可能需要通过Node-API模块来实现以获得更好的性能，通过将这些功能实现为自定义模块并注册到ArkTS环境中，可以在一定程度上提高整体的性能。 |

#### \[h2\]使用示例

**napi\_load\_module**

[使用Node-API接口在主线程中进行模块加载](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/use-napi-load-module)

**napi\_load\_module\_with\_info**

[使用Node-API接口进行模块加载](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/use-napi-load-module-with-info)

**napi\_module\_register**

在ArkTS代码环境中使用Node-API模块编写的代码来实现特定的功能，可以将这部分功能封装成自定义模块，然后通过napi\_module\_register将其注册到ArkTS代码环境中，以实现功能的扩展和复用。

cpp部分代码

#include "napi/native\_api.h"

// 此模块是一个Node-API的回调函数
static napi\_value Add(napi\_env env, napi\_callback\_info info)
{
    // 接受传入两个参数
    size\_t requireArgc = 2;
    size\_t argc = 2;
    napi\_value args\[2\] = {nullptr};
    napi\_get\_cb\_info(env, info, &argc, args , nullptr, nullptr);

    // 将传入的napi\_value类型的参数转化为double类型
    double valueLeft;
    double valueRight;
    napi\_get\_value\_double(env, args\[0\], &valueLeft);
    napi\_get\_value\_double(env, args\[1\], &valueRight);

    // 将转化后的double值相加并转成napi\_value返回给ArkTS代码使用
    napi\_value sum;
    napi\_create\_double(env, valueLeft + valueRight, &sum);

    return sum;
}

// C++函数Init用于初始化插件，用于将ArkTS层的函数或属性与C++层的函数进行关联
EXTERN\_C\_START
static napi\_value Init(napi\_env env, napi\_value exports)
{
    // 通过napi\_property\_descriptor结构体，可以定义需要导出的属性，并在Node-API模块中使用。napi\_define\_properties将属性与实际的C++函数进行关联，使其可以被ArkTS层访问和调用
    napi\_property\_descriptor desc\[\] = {
        { "add", nullptr, Add, nullptr, nullptr, nullptr, napi\_default, nullptr }
    };
    napi\_define\_properties(env, exports, sizeof(desc) / sizeof(desc\[0\]), desc);
    return exports;
}
EXTERN\_C\_END

// 插件的初始化被定义在一个名为demoModule的结构体中，其中包含了模块的基本信息，比如模块的版本号、注册函数等
static napi\_module demoModule = {
    .nm\_version =1,
    .nm\_flags = 0,
    .nm\_filename = nullptr,
    .nm\_register\_func = Init,
    .nm\_modname = "entry",
    .nm\_priv = ((void\*)0),
    .reserved = { 0 },
};

// 在RegisterEntryModule函数中，使用napi\_module\_register函数注册并导出了这个插件
extern "C" \_\_attribute\_\_((constructor)) void RegisterEntryModule(void)
{
    napi\_module\_register(&demoModule);
}

接口声明

export const add: (a: number, b: number) => number; // 模块加载

ArkTS侧示例代码

hilog.info(0x0000, 'testTag', 'Test Node-API 2 + 3 = %{public}d', testNapi.add(2, 3));

#### ArkTS Object相关

#### \[h2\]接口描述

| 接口 | 描述 |
| :-- | :-- |
| napi\_create\_object\_with\_properties | 用于在Node-API模块中使用给定的napi\_property\_descriptor创建ArkTS Object。descriptor的键名必须为string，且不可转为number。 |
| napi\_create\_object\_with\_named\_properties | 用于在Node-API模块中使用给定的napi\_value和键名创建ArkTS Object。键名必须为string，且不可转为number。 |

#### \[h2\]使用示例

**napi\_create\_object\_with\_properties**

用给定的napi\_property\_descriptor作为属性去创建一个ArkTS对象，并且descriptor的键名必须为string，且不可转为number。

cpp部分代码

// ArkTS Object相关 napi\_create\_object\_with\_properties
static napi\_value CreateObjectWithProperties(napi\_env env, napi\_callback\_info info)
{
    size\_t argc = 1;
    napi\_value argv\[1\] = {nullptr};
    // 获取解析传递的参数
    napi\_get\_cb\_info(env, info, &argc, argv, nullptr, nullptr);
    // 声明了一个napi\_property\_descriptor数组desc，其中包含了一个名为"name"的属性，其值为传入的第一个参数argv\[0\]。
    napi\_property\_descriptor desc\[\] = {
        {"name", nullptr, nullptr, nullptr, nullptr, argv\[0\], napi\_default\_jsproperty, nullptr}};
    napi\_value object = nullptr;
    // 调用napi\_create\_object\_with\_properties来创建一个新的ArkTS对象，并将属性值添加到该对象中。
    napi\_create\_object\_with\_properties(env, &object, sizeof(desc) / sizeof(desc\[0\]), desc);
    napi\_valuetype valueType;
    napi\_typeof(env, object, &valueType);
    if (valueType == napi\_object) {
        return object;
    }
}

接口声明

export const createObjectWithProperties: (data: string) => {name:string}; // ArkTS Object相关 napi\_create\_object\_with\_properties

ArkTS侧示例代码

// ArkTS Object相关 napi\_create\_object\_with\_properties
let value1 = testNapi.createObjectWithProperties('createObject');
hilog.info(0x0000, 'testTag', 'Node-API napi\_create\_object\_with\_properties:%{public}s',
  JSON.stringify(value1));

**napi\_create\_object\_with\_named\_properties**

用于使用给定的napi\_value和键名创建一个ArkTS对象，并且给定的键名必须为string，且不可转为number。

cpp部分代码

// ArkTS Object相关 napi\_create\_object\_with\_named\_properties
static napi\_value CreateObjectWithNameProperties(napi\_env env, napi\_callback\_info info)
{
    size\_t argc = 1;
    napi\_value argv\[1\] = {nullptr};
    // 获取解析传递的参数
    napi\_get\_cb\_info(env, info, &argc, argv, nullptr, nullptr);
    napi\_value obj = nullptr;
    const char \*key\[\] = {
        "name",
    };
    const napi\_value values\[\] = {
        argv\[0\],
    };
    napi\_property\_descriptor desc\[\] = {{"name", nullptr, nullptr,
                                        nullptr, nullptr, nullptr, napi\_default, nullptr}};
    napi\_status status = napi\_create\_object\_with\_named\_properties(
        env, &obj, sizeof(desc) / sizeof(desc\[0\]), key, values
    );
    if (status != napi\_ok) {
        return nullptr;
    }
    return obj;
}

接口声明

export const createObjectWithNameProperties: (data: string) => undefined | { name: string }; // ArkTS Object相关 napi\_create\_object\_with\_named\_properties

ArkTS侧示例代码

// ArkTS Object相关 napi\_create\_object\_with\_named\_properties
let value2 = testNapi.createObjectWithNameProperties('ls');
try {
  hilog.info(0x0000, 'testTag', 'Node-API napi\_create\_object\_with\_named\_properties:%{public}s', JSON.stringify(value2));
} catch (error) {
  hilog.error(0x0000, 'testTag', 'Node-API napi\_create\_object\_with\_named\_properties: %{public}s', error.message);
}

#### 运行指定abc文件

#### \[h2\]接口描述

| 接口 | 描述 |
| :-- | :-- |
| napi\_run\_script\_path | 用于在Node-API模块中运行指定abc文件。 |

#### \[h2\]使用示例

**napi\_run\_script\_path**

在Node-API模块中运行abc文件。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/f8/v3/e8o2srEzTZ6yvC87bgDetg/caution_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132814Z&HW-CC-Expire=86400&HW-CC-Sign=0EAB3C6F79B6FC03324F973F0C5353A7E22C6C30253A81DE3131A62C936DAFDA)

在信号函数中调用不安全，直接调用可能导致栈溢出。

cpp部分代码

// 运行指定abc文件 napi\_run\_script\_path
static napi\_value RunScriptPath(napi\_env env, napi\_callback\_info info)
{
    napi\_value value = nullptr;
    // 注意：记得在应用rawfile目录下放置.abc文件
    const char \*scriptPath = "/entry/resources/rawfile/test.abc";
    // 使用napi\_run\_script\_path函数执行指定路径中的文件
    napi\_status status = napi\_run\_script\_path(env, scriptPath, &value);
    // 检查是否执行成功，如果失败，返回false
    napi\_value returnValue = nullptr;
    if (value == nullptr || status != napi\_ok) {
        napi\_get\_boolean(env, false, &returnValue);
    } else {
        napi\_get\_boolean(env, true, &returnValue);
    }
    return returnValue;
}

接口声明

export const runScriptPath: () => boolean; // 运行指定abc文件 napi\_run\_script\_path

ArkTS侧示例代码

// 运行指定abc文件 napi\_run\_script\_path
try { // 在此处执行错误返回false，成功就返回true
  hilog.info(0x0000, 'testTag', 'Test Node-API napi\_run\_script\_path: %{public}s',
    testNapi.runScriptPath());
  // ···
} catch (error) {
  hilog.error(0x0000, 'testTag', 'Test Node-API napi\_run\_script\_path errorMessage: %{public}s',
    error.message);
  // ···
}

test.js代码，将JS代码编译为.abc文件，步骤如下：

1.  在SDK的ets/build-tools/ets-loader/bin/ark/build-win/bin目录下放置test.js文件
2.  执行命令如es2abc.exe test.js --output test.abc后便可生成test.abc文件

放入指定路径中：/entry/resources/rawfile

function add(a, b) {
  return a + b;
}
add(1, 2);

#### 异步工作对象加入队列并指定优先级

#### \[h2\]接口描述

| 接口 | 描述 |
| :-- | :-- |
| napi\_queue\_async\_work\_with\_qos | 用于将异步工作对象加入队列，让开发者能够根据QoS优先级来管理和调度异步工作的执行，从而更好地满足程序的性能和响应需求。 |

#### \[h2\]使用示例

**napi\_queue\_async\_work\_with\_qos**

将异步工作对象加到队列，由底层根据传入的qos优先级去调度执行。

#### 给ArkTS对象绑定回调和回调所需的参数

#### \[h2\]接口描述

| 接口 | 描述 |
| :-- | :-- |
| napi\_coerce\_to\_native\_binding\_object | 用于给ArkTS对象绑定回调和回调所需的参数，其作用是为了给ArkTS对象携带Native信息。 |

#### \[h2\]使用示例

**napi\_coerce\_to\_native\_binding\_object**

用于给ArkTS Object绑定回调和回调所需的参数，给ArkTS Object携带Native信息。

cpp部分代码

#include <hilog/log.h>
#include <mutex>
#include <unordered\_set>
#include "napi/native\_api.h"

class Object {
public:
    Object() = default;
    ~Object() = default;

    static Object\* GetInstance()
    {
        Object\* instance = new Object();
        return instance;
    }

    static napi\_value GetAddress(napi\_env env, napi\_callback\_info info)
    {
        napi\_value thisVar = nullptr;
        napi\_get\_cb\_info(env, info, nullptr, nullptr, &thisVar, nullptr);
        if (thisVar == nullptr) {
            return nullptr;
        }
        void\* object = nullptr;
        napi\_unwrap(env, thisVar, &object);
        if (object == nullptr) {
            return nullptr;
        }
        uint64\_t addressVal = reinterpret\_cast<uint64\_t>(object);
        napi\_value address = nullptr;
        napi\_create\_bigint\_uint64(env, addressVal, &address);
        return address;
    }

    // 获取数组大小
    static napi\_value GetSetSize(napi\_env env, napi\_callback\_info info)
    {
        napi\_value thisVar = nullptr;
        napi\_get\_cb\_info(env, info, nullptr, nullptr, &thisVar, nullptr);
        if (thisVar == nullptr) {
            return nullptr;
        }
        void\* object = nullptr;
        napi\_unwrap(env, thisVar, &object);
        if (object == nullptr) {
            return nullptr;
        }
        std::lock\_guard<std::mutex> lock(reinterpret\_cast<Object\*>(object)->numberSetMutex\_);
        uint32\_t setSize = reinterpret\_cast<Object\*>(object)->numberSet\_.size();
        napi\_value napiSize = nullptr;
        napi\_create\_uint32(env, setSize, &napiSize);
        return napiSize;
    }

    // 往数组里插入元素
    static napi\_value Store(napi\_env env, napi\_callback\_info info)
    {
        size\_t argc = 1;
        napi\_value args\[1\] = {nullptr};
        napi\_value thisVar = nullptr;
        napi\_get\_cb\_info(env, info, &argc, args, &thisVar, nullptr);
        if (argc != 1) {
            napi\_throw\_error(env, nullptr, "Store args number must be one.");
            return nullptr;
        }
        napi\_valuetype type = napi\_undefined;
        napi\_typeof(env, args\[0\], &type);
        if (type != napi\_number) {
            napi\_throw\_error(env, nullptr, "Store args is not number.");
            return nullptr;
        }
        if (thisVar == nullptr) {
            return nullptr;
        }
        uint32\_t value = 0;
        napi\_get\_value\_uint32(env, args\[0\], &value);
        void\* object = nullptr;
        napi\_unwrap(env, thisVar, &object);
        if (object == nullptr) {
            return nullptr;
        }
        std::lock\_guard<std::mutex> lock(reinterpret\_cast<Object\*>(object)->numberSetMutex\_);
        reinterpret\_cast<Object \*>(object)-> numberSet\_.insert(value);
        return nullptr;
    }

    // 删除数组元素
    static napi\_value Erase(napi\_env env, napi\_callback\_info info)
    {
        size\_t argc = 1;
        napi\_value args\[1\] = {nullptr};
        napi\_value thisVar = nullptr;
        napi\_get\_cb\_info(env, info, &argc, args, &thisVar, nullptr);
        if (argc != 1) {
            napi\_throw\_error(env, nullptr, "Erase args number must be one.");
            return nullptr;
        }
        napi\_valuetype type = napi\_undefined;
        napi\_typeof(env, args\[0\], &type);
        if (type != napi\_number) {
            napi\_throw\_error(env, nullptr, "Erase args is not number.");
            return nullptr;
        }
        if (thisVar == nullptr) {
            return nullptr;
        }
        uint32\_t value = 0;
        napi\_get\_value\_uint32(env, args\[0\], &value);
        void\* object = nullptr;
        napi\_unwrap(env, thisVar, &object);
        if (object == nullptr) {
            return nullptr;
        }
        std::lock\_guard<std::mutex> lock(reinterpret\_cast<Object\*>(object)->numberSetMutex\_);
        reinterpret\_cast<Object \*>(object)->numberSet\_.erase(value);
        return nullptr;
    }

    // 清空数组
    static napi\_value Clear(napi\_env env, napi\_callback\_info info)
    {
        napi\_value thisVar = nullptr;
        napi\_get\_cb\_info(env, info, nullptr, nullptr, &thisVar, nullptr);
        if (thisVar == nullptr) {
            return nullptr;
        }
        void\* object = nullptr;
        napi\_unwrap(env, thisVar, &object);
        if (object == nullptr) {
            return nullptr;
        }
        std::lock\_guard<std::mutex> lock(reinterpret\_cast<Object\*>(object)->numberSetMutex\_);
        reinterpret\_cast<Object \*>(object)->numberSet\_.clear();
        return nullptr;
    }

private:
    Object(const Object &) = delete;
    Object &operator=(const Object &) = delete;

    std::unordered\_set<uint32\_t> numberSet\_{};
    std::mutex numberSetMutex\_{};
};

void FinalizerCallback(napi\_env env, void \*data, void \*hint)
{
    return;
}

// 解绑回调，在序列化时调用，可在对象解绑时执行一些清理操作
void\* DetachCallback(napi\_env env, void \*value, void \*hint)
{
    return value;
}

// 绑定回调，在反序列化时调用
napi\_value AttachCallback(napi\_env env, void\* value, void\* hint)
{
    napi\_value object = nullptr;
    napi\_create\_object(env, &object);
    napi\_property\_descriptor desc\[\] = {
        {"getAddress", nullptr, Object::GetAddress, nullptr, nullptr, nullptr, napi\_default, nullptr},
        {"getSetSize", nullptr, Object::GetSetSize, nullptr, nullptr, nullptr, napi\_default, nullptr},
        {"store", nullptr, Object::Store, nullptr, nullptr, nullptr, napi\_default, nullptr},
        {"erase", nullptr, Object::Erase, nullptr, nullptr, nullptr, napi\_default, nullptr},
        {"clear", nullptr, Object::Clear, nullptr, nullptr, nullptr, napi\_default, nullptr}};
    napi\_define\_properties(env, object, sizeof(desc) / sizeof(desc\[0\]), desc);
    // 将JS对象object和native对象value生命周期进行绑定
    napi\_status status = napi\_wrap(env, object, value, FinalizerCallback, nullptr, nullptr);
    if (status != napi\_ok) {
        OH\_LOG\_INFO(LOG\_APP, "Node-API attachCallback is failed.");
    }
    // JS对象携带native信息
    napi\_coerce\_to\_native\_binding\_object(env, object, DetachCallback, AttachCallback, value, hint);
    return object;
}

EXTERN\_C\_START
static napi\_value Init(napi\_env env, napi\_value exports)
{
    napi\_property\_descriptor desc\[\] = {
        {"getAddress", nullptr, Object::GetAddress, nullptr, nullptr, nullptr, napi\_default, nullptr},
        {"getSetSize", nullptr, Object::GetSetSize, nullptr, nullptr, nullptr, napi\_default, nullptr},
        {"store", nullptr, Object::Store, nullptr, nullptr, nullptr, napi\_default, nullptr},
        {"erase", nullptr, Object::Erase, nullptr, nullptr, nullptr, napi\_default, nullptr},
        {"clear", nullptr, Object::Clear, nullptr, nullptr, nullptr, napi\_default, nullptr}};
    napi\_define\_properties(env, exports, sizeof(desc) / sizeof(desc\[0\]), desc);
    auto object = Object::GetInstance();
    napi\_status status = napi\_wrap(env, exports, reinterpret\_cast<void\*>(object), FinalizerCallback, nullptr, nullptr);
    if (status != napi\_ok) {
        OH\_LOG\_INFO(LOG\_APP, "Node-API napi\_wrap is failed.");
    }
    napi\_coerce\_to\_native\_binding\_object(env, exports, DetachCallback, AttachCallback, reinterpret\_cast<void\*>(object),
                                         nullptr);
    return exports;
}
EXTERN\_C\_END

static napi\_module demoModule = {
    .nm\_version = 1,
    .nm\_flags = 0,
    .nm\_filename = nullptr,
    .nm\_register\_func = Init,
    .nm\_modname = "entry",
    .nm\_priv = ((void\*)0),
    .reserved = { 0 },
};

extern "C" \_\_attribute\_\_((constructor)) void RegisterEntryModule(void)
{
    napi\_module\_register(&demoModule);
}

接口声明

// 给ArkTS对象绑定回调和回调所需的参数 napi\_coerce\_to\_native\_binding\_object
export const getAddress: () => number;

export const getSetSize: () => number;

export const store: (a: number) => void;

export const erase: (a: number) => void;

export const clear: () => void;

ArkTS侧示例代码

// index.ets
import testNapi from 'libentry.so';
import { taskpool } from '@kit.ArkTS';

@Concurrent
function getAddress() {
  let address: number = testNapi.getAddress();
  console.info("taskpool:: address is " + address);
}

@Concurrent
function store(a:number, b:number, c:number) {
  let size:number = testNapi.getSetSize();
  console.info("set size is " + size + " before store");
  testNapi.store(a);
  testNapi.store(b);
  testNapi.store(c);
  size = testNapi.getSetSize();
  console.info("set size is " + size + " after store");
}

@Concurrent
function erase(a:number) {
  let size:number = testNapi.getSetSize();
  console.info("set size is " + size + " before erase");
  testNapi.erase(a);
  size = testNapi.getSetSize();
  console.info("set size is " + size + " after erase");
}

@Concurrent
function clear() {
  let size:number = testNapi.getSetSize();
  console.info("set size is " + size + " before clear");
  testNapi.clear();
  size = testNapi.getSetSize();
  console.info("set size is " + size + " after clear");
}

async function test01(): Promise<void> {
    let address:number = testNapi.getAddress();
    console.info("host thread address is " + address);

    let task1 = new taskpool.Task(getAddress);
    await taskpool.execute(task1);

    let task2 = new taskpool.Task(store, 1, 2, 3);
    await taskpool.execute(task2);

    let task3 = new taskpool.Task(store, 4, 5, 6);
    await taskpool.execute(task3);

    let task4 = new taskpool.Task(erase, 3);
    await taskpool.execute(task4);

    let task5 = new taskpool.Task(erase, 5);
    await taskpool.execute(task5);

    let task6 = new taskpool.Task(clear);
    await taskpool.execute(task6);
}

test01();

**注意事项**

对ArkTS对象A调用napi\_coerce\_to\_native\_binding\_object将开发者实现的detach/attach回调和native对象信息加到A上，再将A跨线程传递。跨线程传递需要对A进行序列化和反序列化。此处的序列化与反序列化是人为控制的，需要调用后文介绍的napi\_serialize、napi\_deserialize接口。过程如下图所示：在当前线程thread1序列化A得到数据data，序列化阶段执行detach回调。然后将data传给目标线程thread2，在thread2中反序列化data，执行attach回调，最终得到ArkTS对象A。此处的detach/attach是告知开发者序列化与反序列化执行完毕的回调。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/82/v3/tcgSJVZ5Sg2fMSSheXRynQ/zh-cn_image_0000002633850232.png?HW-CC-KV=V1&HW-CC-Date=20260709T132814Z&HW-CC-Expire=86400&HW-CC-Sign=785599D570D947A91D41BFBB6A1391D8F5B7BC70AF20730662FA467AE08A521F)

#### 事件循环

#### \[h2\]接口描述

| 接口 | 描述 |
| :-- | :-- |
| napi\_run\_event\_loop | 触发底层的事件循环。 |
| napi\_stop\_event\_loop | 停止底层的事件循环。 |

#### \[h2\]使用示例

**napi\_run\_event\_loop、napi\_stop\_event\_loop**

[使用扩展的Node-API接口在异步线程中运行和停止事件循环](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/use-napi-event-loop)

#### ArkTS基础运行时环境

#### \[h2\]接口描述

| 接口 | 描述 |
| :-- | :-- |
| napi\_create\_ark\_runtime | 创建基础运行时环境。 |
| napi\_destroy\_ark\_runtime | 销毁基础运行时环境。 |

#### \[h2\]使用示例

**napi\_create\_ark\_runtime、napi\_destroy\_ark\_runtime**

[使用Node-API接口创建ArkTS运行时环境](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/use-napi-ark-runtime)

#### 序列化和反序列化

#### \[h2\]接口描述

| 接口 | 描述 |
| :-- | :-- |
| napi\_serialize | 将ArkTS对象转换为native数据。第一个参数env是接口执行的ArkTS环境；第二个参数object是待序列化的ArkTS对象；第三个参数transfer\_list是存放需要以transfer传递的arrayBuffer的array，如不涉及可传undefined；第四个参数clone\_list是存放需要克隆传递的Sendable对象的array，如不涉及可传undefined；第五个参数result是序列化结果。 |
| napi\_deserialize | 将native数据转为ArkTS对象。第一个参数env是接口执行的ArkTS环境；第二个参数buffer是序列化数据；第三个参数object是反序列化得到的结果。 |
| napi\_delete\_serialization\_data | 删除序列化数据。 |

#### \[h2\]使用示例

**napi\_serialize、napi\_deserialize、napi\_delete\_serialization\_data**

用于将ArkTS对象转换为native数据、将native数据转为ArkTS对象、删除序列化数据等操作。

cpp部分代码

// 序列化和反序列化
static napi\_value AboutSerialize(napi\_env env, napi\_callback\_info info)
{
    // 获取传入的ts的一个对象作为参数
    size\_t argc = 1;
    napi\_value args\[1\] = {nullptr};
    napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr);
    napi\_value undefined = nullptr;
    // 构造napi\_serialize方法所需参数
    napi\_get\_undefined(env, &undefined);
    void \*data = nullptr;
    // 调用napi\_serialize方法将ts对象转化为native数据
    napi\_status status = napi\_serialize(env, args\[0\], undefined, undefined, &data);
    if (status != napi\_ok || data == nullptr) {
        napi\_throw\_error(env, nullptr, "Node-API napi\_serialize fail");
        return nullptr;
    }
    // 构造napi\_value类型的数据，用于接收将native数据转化为ts对象后的数据
    napi\_value result = nullptr;
    napi\_deserialize(env, data, &result);
    napi\_value number = nullptr;
    // 获取native数据转化为ts对象后的数据中的numKey属性的值
    napi\_get\_named\_property(env, result, "numKey", &number);
    // 判断获取到的属性值是否为number类型
    napi\_valuetype valuetype;
    napi\_typeof(env, number, &valuetype);
    if (valuetype != napi\_number) {
        napi\_throw\_error(env, nullptr, "Node-API Wrong type of argument. Expects a number.");
        return nullptr;
    }
    // 调用napi\_delete\_serialization\_data方法删除序列化数据
    napi\_delete\_serialization\_data(env, data);
    // 返回获取到的属性值
    return number;
}

接口声明

export const aboutSerialize: (obj: {numKey:number}) => number | undefined; // 序列化和反序列化

ArkTS侧示例代码

class Obj {
  numKey: number = 0;
}

// 序列化和反序列化
let obj: Obj = { numKey: 500 };
hilog.info(0x0000, 'testTag', ' Node-API aboutSerialize: %{public}d', testNapi.aboutSerialize(obj));

#### 根据任务指定的优先级和入队方式进行处理异步线程向ArkTS线程投递的任务

#### \[h2\]接口描述

| 接口 | 描述 |
| :-- | :-- |
| napi\_call\_threadsafe\_function\_with\_priority | 将指定优先级和入队方式的任务投递到ArkTS主线程。 |

#### \[h2\]使用示例

**napi\_call\_threadsafe\_function\_with\_priority**

[使用Node-API接口从异步线程向ArkTS线程投递指定优先级和入队方式的的任务](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/use-call-threadsafe-function-with-priority)

#### Sendable相关

#### \[h2\]接口描述

| 接口 | 描述 |
| :-- | :-- |
| napi\_is\_sendable | 判断给定ArkTS value是否是Sendable的。 |
| napi\_define\_sendable\_class | 创建一个sendable类。 |
| napi\_create\_sendable\_object\_with\_properties | 使用给定的napi\_property\_descriptor创建一个sendable对象。 |
| napi\_create\_sendable\_array | 创建一个sendable数组。 |
| napi\_create\_sendable\_array\_with\_length | 创建一个指定长度的sendable数组。 |
| napi\_create\_sendable\_arraybuffer | 创建一个sendable ArrayBuffer。 |
| napi\_create\_sendable\_typedarray | 创建一个sendable TypedArray。 |
| napi\_wrap\_sendable | 包裹一个native实例到ArkTS对象中。 |
| napi\_wrap\_sendable\_with\_size | 包裹一个native实例到ArkTS对象中并指定大小。 |
| napi\_unwrap\_sendable | 获取ArkTS对象包裹的native实例。 |
| napi\_remove\_wrap\_sendable | 移除并获取ArkTS对象包裹的native实例，移除后回调将不再触发，需手动delete释放内存。 |

#### \[h2\]使用示例

**napi\_is\_sendable**

判断给定ArkTS value是否是Sendable的。

cpp部分代码

// Sendable相关 napi\_is\_sendable
static napi\_value IsSendable(napi\_env env, napi\_callback\_info info)
{
    size\_t argc = 1;
    napi\_value args\[1\] = {nullptr};
    napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr);
    bool isSendable = false;
    napi\_is\_sendable(env, args\[0\], &isSendable);
    napi\_value result;
    napi\_get\_boolean(env, isSendable, &result);
    return result;
}

接口声明

export const isSendable: <T>(a: T) => boolean; // Sendable相关 napi\_is\_sendable

ArkTS侧示例代码

// Sendable相关 napi\_is\_sendable
let value = testNapi.isSendable('createObject');
hilog.info(0x0000, 'testTag', 'Node-API napi\_is\_sendable: %{public}s', JSON.stringify(value));

**napi\_define\_sendable\_class**

创建一个sendable类。

cpp部分代码

#include "napi/native\_api.h"

static napi\_value func(napi\_env env, napi\_callback\_info info) {
    napi\_value val;
    napi\_create\_string\_utf8(env, "func result", NAPI\_AUTO\_LENGTH, &val);
    return val;
}

static napi\_value DefineSendableClass(napi\_env env) {
    napi\_value str;
    napi\_create\_string\_utf8(env, "str", NAPI\_AUTO\_LENGTH, &str);

    napi\_property\_descriptor props\[\] = {
        {"staticStr", nullptr, nullptr, nullptr, nullptr, str,
         static\_cast<napi\_property\_attributes>(napi\_static | napi\_writable), nullptr},
        {"staticFunc", nullptr, func, nullptr, nullptr, nullptr, napi\_static, nullptr},
        {"str", nullptr, nullptr, nullptr, nullptr, str, static\_cast<napi\_property\_attributes>(1 << 9 | napi\_writable),
         nullptr},
        {"func", nullptr, nullptr, nullptr, nullptr, nullptr,
         static\_cast<napi\_property\_attributes>(1 << 11 | napi\_writable), nullptr},
    };

    napi\_value sendableClass = nullptr;
    napi\_define\_sendable\_class(
        env, "SendableClass", NAPI\_AUTO\_LENGTH,
        \[\](napi\_env env, napi\_callback\_info info) -> napi\_value {
            napi\_value thisVar = nullptr;
            napi\_get\_cb\_info(env, info, nullptr, nullptr, &thisVar, nullptr);
            napi\_value str;
            napi\_create\_string\_utf8(env, "instance str", NAPI\_AUTO\_LENGTH, &str);
            napi\_property\_descriptor props\[\] = {
                {"str", nullptr, nullptr, nullptr, nullptr, str, napi\_default, nullptr},
                {"func", nullptr, func, nullptr, nullptr, nullptr, napi\_default, nullptr},
            };
            napi\_define\_properties(env, thisVar, sizeof(props) / sizeof(props\[0\]), props);
            return thisVar;
        },
        nullptr, sizeof(props) / sizeof(props\[0\]), props, nullptr, &sendableClass);

    return sendableClass;
}

EXTERN\_C\_START
static napi\_value Init(napi\_env env, napi\_value exports)
{
    napi\_property\_descriptor desc\[\] = {};
    napi\_define\_properties(env, exports, sizeof(desc) / sizeof(desc\[0\]), desc);
    napi\_value cons = DefineSendableClass(env);
    napi\_set\_named\_property(env, exports, "SendableClass", cons);
    return exports;
}
EXTERN\_C\_END

static napi\_module demoModule = {
    .nm\_version = 1,
    .nm\_flags = 0,
    .nm\_filename = nullptr,
    .nm\_register\_func = Init,
    .nm\_modname = "entry",
    .nm\_priv = ((void\*)0),
    .reserved = { 0 },
};

extern "C" \_\_attribute\_\_((constructor)) void RegisterEntryModule(void)
{
    napi\_module\_register(&demoModule);
}

接口声明

@Sendable
export class SendableClass {
  static staticStr: string;
  static staticFunc(): string;
  str: string;
  func(): string;
} // Sendable相关 napi\_define\_sendable\_class

ArkTS侧示例代码

// Sendable相关 napi\_define\_sendable\_class
let value = new testNapi.SendableClass();
hilog.info(0x0000, 'testTag', 'Node-API napi\_define\_sendable\_class: %{public}s', value.str);

**napi\_create\_sendable\_object\_with\_properties**

使用给定的napi\_property\_descriptor创建一个sendable对象。

cpp部分代码

// Sendable相关 napi\_create\_sendable\_object\_with\_properties
static napi\_value GetSendableObject(napi\_env env, napi\_callback\_info info)
{
    napi\_value val\_true;
    napi\_get\_boolean(env, true, &val\_true);
    napi\_property\_descriptor desc1\[\] = {
        {"x", nullptr, nullptr, nullptr, nullptr, val\_true, napi\_default\_jsproperty, nullptr},
    };
    napi\_value obj;
    napi\_create\_sendable\_object\_with\_properties(env, 1, desc1, &obj);
    return obj;
}

接口声明

export const getSendableObject: () => { x: true }; // Sendable相关 napi\_create\_sendable\_object\_with\_properties

ArkTS侧示例代码

// Sendable相关 napi\_create\_sendable\_object\_with\_properties
let value = testNapi.getSendableObject();
hilog.info(0x0000, 'testTag', 'Node-API napi\_create\_sendable\_object\_with\_properties: %{public}s',
  JSON.stringify(value));

**napi\_create\_sendable\_array**

创建一个sendable数组。

cpp部分代码

// Sendable相关 napi\_create\_sendable\_array
static napi\_value GetSendableArray(napi\_env env, napi\_callback\_info info)
{
    napi\_value result = nullptr;
    napi\_create\_sendable\_array(env, &result);
    return result;
}

接口声明

export const getSendableArray: () => \[\]; // Sendable相关 napi\_create\_sendable\_array

ArkTS侧示例代码

// Sendable相关 napi\_create\_sendable\_array
let value = testNapi.getSendableArray();
hilog.info(0x0000, 'testTag', 'Node-API napi\_create\_sendable\_array: %{public}s',
  JSON.stringify(value));

**napi\_create\_sendable\_array\_with\_length**

创建一个指定长度的sendable数组。

cpp部分代码

// Sendable相关 napi\_create\_sendable\_array\_with\_length
static napi\_value GetSendableArrayWithLength(napi\_env env, napi\_callback\_info info)
{
    napi\_value result = nullptr;
    napi\_create\_sendable\_array\_with\_length(env, 1, &result);
    return result;
}

接口声明

// index.d.ts
export const getSendableArrayWithLength: () => \[\];

ArkTS侧示例代码

let value = testNapi.getSendableArrayWithLength();
hilog.info(0x0000, 'testTag', 'Node-API napi\_create\_sendable\_array\_with\_length: %{public}s', JSON.stringify(value.length));

**napi\_create\_sendable\_arraybuffer**

创建一个sendable ArrayBuffer。

cpp部分代码

static napi\_value GetSendableArrayBuffer(napi\_env env, napi\_callback\_info info) {
    static size\_t LENGTH = 1024;
    void \*data;
    napi\_value result = nullptr;
    napi\_create\_sendable\_arraybuffer(env, LENGTH, &data, &result);
    bool isArrayBuffer = false;
    napi\_is\_arraybuffer(env, result, &isArrayBuffer);
    OH\_LOG\_INFO(LOG\_APP, "isArrayBuffer: %{public}d", isArrayBuffer);
    return result;
}

接口声明

// index.d.ts
export const getSendableArrayBuffer: () => ArrayBuffer;

ArkTS侧示例代码

testNapi.getSendableArrayBuffer();

**napi\_create\_sendable\_typedarray**

创建一个sendable TypedArray。

cpp部分代码

static napi\_value GetSendableTypedArray(napi\_env env, napi\_callback\_info info) {
    static size\_t LENGTH = 1024;
    static size\_t OFFSET = 0;
    void \*data;
    napi\_value arraybuffer = nullptr;
    napi\_create\_sendable\_arraybuffer(env, LENGTH, &data, &arraybuffer);

    napi\_value result = nullptr;
    napi\_create\_sendable\_typedarray(env, napi\_uint8\_array, LENGTH, arraybuffer, OFFSET, &result);
    bool isTypedArray = false;
    napi\_is\_typedarray(env, result, &isTypedArray);
    OH\_LOG\_INFO(LOG\_APP, "isTypedArray: %{public}d", isTypedArray);
    return result;
}

接口声明

// index.d.ts
export const getSendableTypedArray: () => void;

ArkTS侧示例代码

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

testNapi.getSendableTypedArray();

**napi\_wrap\_sendable**

包裹一个native实例到ArkTS对象中。

cpp部分代码

#include "napi/native\_api.h"

static napi\_value WrapSendable(napi\_env env, napi\_callback\_info info) {
    napi\_value val\_true;
    napi\_get\_boolean(env, true, &val\_true);
    napi\_property\_descriptor desc1\[\] = {
        {"x", nullptr, nullptr, nullptr, nullptr, val\_true, napi\_default\_jsproperty, nullptr},
    };
    napi\_value obj;
    napi\_create\_sendable\_object\_with\_properties(env, 1, desc1, &obj);

    const char\* testStr = "test";
    napi\_wrap\_sendable(env, obj, (void\*)testStr, \[\](napi\_env env, void\* data, void\* hint) {}, nullptr);

    return nullptr;
}

接口声明

// index.d.ts
export const wrapSendable: () => void;

ArkTS侧示例代码

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

testNapi.wrapSendable();

**napi\_wrap\_sendable\_with\_size**

包裹一个native实例到ArkTS对象中并指定大小。

cpp部分代码

#include "napi/native\_api.h"

static napi\_value WrapSendableWithSize(napi\_env env, napi\_callback\_info info) {
    napi\_value val\_true;
    napi\_get\_boolean(env, true, &val\_true);
    napi\_property\_descriptor desc1\[\] = {
        {"x", nullptr, nullptr, nullptr, nullptr, val\_true, napi\_default\_jsproperty, nullptr},
    };
    napi\_value obj;
    napi\_create\_sendable\_object\_with\_properties(env, 1, desc1, &obj);

    const char\* testStr = "test";
    napi\_wrap\_sendable\_with\_size(env, obj, (void\*)testStr, \[\](napi\_env env, void\* data, void\* hint) {}, nullptr, 100);

    return nullptr;
}

接口声明

// index.d.ts
export const wrapSendableWithSize: () => void;

ArkTS侧示例代码

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

testNapi.wrapSendableWithSize();

**napi\_unwrap\_sendable**

获取ArkTS对象包裹的native实例。

cpp部分代码

#include "napi/native\_api.h"

static napi\_value UnwrapSendable(napi\_env env, napi\_callback\_info info) {
    napi\_value val\_true;
    napi\_get\_boolean(env, true, &val\_true);
    napi\_property\_descriptor desc1\[\] = {
        {"x", nullptr, nullptr, nullptr, nullptr, val\_true, napi\_default\_jsproperty, nullptr},
    };
    napi\_value obj;
    napi\_create\_sendable\_object\_with\_properties(env, 1, desc1, &obj);

    const char\* testStr = "test";
    napi\_wrap\_sendable(env, obj, (void\*)testStr, \[\](napi\_env env, void\* data, void\* hint) {}, nullptr);

    char\* tmpTestStr = nullptr;
    napi\_unwrap\_sendable(env, obj, (void\*\*)&tmpTestStr);
    OH\_LOG\_INFO(LOG\_APP, "native value is %{public}s", tmpTestStr);

    return nullptr;
}

接口声明

// index.d.ts
export const unwrapSendable: () => void;

ArkTS侧示例代码

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

testNapi.unwrapSendable();

**napi\_remove\_wrap\_sendable**

移除并获取ArkTS对象包裹的native实例，移除后回调将不再触发，需手动delete释放内存。

cpp部分代码

#include "napi/native\_api.h"

static napi\_value RemoveWrapSendable(napi\_env env, napi\_callback\_info info) {
    napi\_value val\_true;
    napi\_get\_boolean(env, true, &val\_true);
    napi\_property\_descriptor desc1\[\] = {
        {"x", nullptr, nullptr, nullptr, nullptr, val\_true, napi\_default\_jsproperty, nullptr},
    };
    napi\_value obj;
    napi\_create\_sendable\_object\_with\_properties(env, 1, desc1, &obj);

    const char\* testStr = "test";
    napi\_wrap\_sendable(env, obj, (void\*)testStr, \[\](napi\_env env, void\* data, void\* hint) {}, nullptr);

    char\* tmpTestStr = nullptr;
    napi\_remove\_wrap\_sendable(env, obj, (void\*\*)&tmpTestStr);
    OH\_LOG\_INFO(LOG\_APP, "native value is %{public}s", tmpTestStr);

    return nullptr;
}

接口声明

// index.d.ts
export const removeWrapSendable: () => void;

ArkTS侧示例代码

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

testNapi.removeWrapSendable();

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

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

#### napi\_wrap接口增强

#### \[h2\]接口描述

| 接口 | 描述 |
| :-- | :-- |
| napi\_wrap\_enhance | 在ArkTS对象上绑定一个native对象实例并指定实例大小，运行时会统计传入的实例大小并将其累加，当累计大小达到GC触发阈值时，运行时会启动垃圾回收流程。开发者可以指定绑定的回调函数是否异步执行，如果是异步执行，回调函数必须保证是线程安全的。 |

#### \[h2\]使用示例

**napi\_wrap\_enhance**

在ArkTS对象上绑定一个native对象实例并指定实例大小，运行时会统计传入的实例大小并将其累加，当累计大小达到GC触发阈值时，运行时会启动垃圾回收流程。开发者可以指定绑定的回调函数是否异步执行，如果是异步执行，回调函数必须保证是线程安全的。

cpp部分代码

#include "napi/native\_api.h"

static napi\_value TestNapiWrapEnhance(napi\_env env, napi\_callback\_info info)
{
    napi\_value testClass = nullptr;
    napi\_define\_class(
        env, "TestClass", NAPI\_AUTO\_LENGTH,
        \[\](napi\_env env, napi\_callback\_info info) -> napi\_value {
            napi\_value thisVar = nullptr;
            napi\_get\_cb\_info(env, info, nullptr, nullptr, &thisVar, nullptr);
            return thisVar;
        },
        nullptr, 0, nullptr, &testClass);

    napi\_value obj = nullptr;
    napi\_new\_instance(env, testClass, 0, nullptr, &obj);
    const char\* testStr = "test";
    napi\_ref wrappedRef = nullptr;
    napi\_wrap\_enhance(env, obj, (void\*)testStr, \[\](napi\_env env, void\* data, void\* hint) {}, false, nullptr, sizeof(testStr), &wrappedRef);
    return nullptr;
}

接口声明

// index.d.ts
export const testNapiWrapEnhance: () => void;

ArkTS侧示例代码

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

testNapi.testNapiWrapEnhance();

#### napi提供多上下文环境能力

#### \[h2\]接口描述

| 接口 | 描述 |
| :-- | :-- |
| napi\_create\_ark\_context | 创建基础运行时上下文环境。 |
| napi\_switch\_ark\_context | 切换到指定的运行时上下文环境。 |
| napi\_destroy\_ark\_context | 销毁基础运行时上下文环境。 |

#### \[h2\]使用示例

**napi\_create\_ark\_context、napi\_switch\_ark\_context、napi\_destroy\_ark\_context**

[使用扩展的Node-API接口创建、切换和销毁上下文环境](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/use-napi-about-context)

#### napi提供通过指针访问ArkTS String内存数据的功能

#### \[h2\]接口描述

| 接口 | 描述 |
| :-- | :-- |
| napi\_get\_buffer\_string\_utf16\_in\_critical\_scope | 获取以Utf16编码的ArkTS String的内存数据缓冲区 |

#### \[h2\]使用示例

**napi\_get\_buffer\_string\_utf16\_in\_critical\_scope**

[使用扩展的Node-API接口创建和销毁临界区作用域及访问字符串内容](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/use-napi-about-critical)

#### napi实现临界区作用域

#### \[h2\]接口描述

| 接口 | 描述 |
| :-- | :-- |
| napi\_open\_critical\_scope | 打开临界区作用域 |
| napi\_close\_critical\_scope | 关闭临界区作用域 |

#### \[h2\]使用示例

**napi\_open\_critical\_scope、napi\_close\_critical\_scope**

[使用扩展的Node-API接口创建和销毁临界区作用域及访问字符串内容](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/use-napi-about-critical)

#### napi支持创建轻量级的强引用对象

#### \[h2\]接口描述

| 接口 | 描述 |
| :-- | :-- |
| napi\_create\_strong\_reference | 创建指向ArkTS对象的强引用 |
| napi\_delete\_strong\_reference | 删除强引用 |
| napi\_get\_strong\_reference\_value | 根据强引用对象获取其关联的ArkTS对象值 |

#### \[h2\]使用示例

**napi\_create\_strong\_reference、napi\_delete\_strong\_reference、napi\_get\_value\_strong\_reference**

[使用扩展的Node-API接口创建、销毁和使用强引用对象](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/use-napi-about-strong-reference)

#### napi支持创建Sendable的强引用

#### \[h2\]接口描述

| 接口 | 描述 |
| :-- | :-- |
| napi\_create\_strong\_sendable\_reference | 创建指向Sendable ArkTS对象的Sendable强引用。 |
| napi\_delete\_strong\_sendable\_reference | 删除Sendable强引用。 |
| napi\_get\_strong\_sendable\_reference\_value | 根据Sendable强引用获取其关联的ArkTS对象值。 |

#### \[h2\]使用示例

**napi\_create\_strong\_sendable\_reference、napi\_delete\_strong\_sendable\_reference、napi\_get\_strong\_sendable\_reference\_value**

[使用扩展的Node-API接口创建、销毁和使用Sendable强引用](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/use-napi-about-sendable-reference)

#### napi支持抛出错误对象的code属性类型为number的ArkTS Error

#### \[h2\]接口描述

| 接口 | 描述 |
| :-- | :-- |
| napi\_throw\_business\_error | 抛出带文本信息的ArkTS Error，其错误对象的code属性类型为number。 |

#### \[h2\]使用示例

**napi\_throw\_business\_error**

[使用扩展的Node-API接口抛出ArkTS异常](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/use-napi-about-error)

#### napi支持基于调用点内联缓存的快速属性访问

#### \[h2\]接口描述

| 接口 | 描述 |
| :-- | :-- |
| napi\_create\_callsite\_info | 创建调用点信息句柄，用于缓存属性访问的内联缓存信息。 |
| napi\_delete\_callsite\_info | 删除调用点信息句柄，释放关联的缓存资源。 |
| napi\_get\_property\_with\_callsite\_info | 使用调用点信息快速获取对象属性值，在缓存命中时跳过常规属性查找流程。 |
| napi\_set\_property\_with\_callsite\_info | 使用调用点信息快速设置对象属性值，在缓存命中时跳过常规属性设置流程。 |

#### \[h2\]使用示例

**napi\_create\_callsite\_info、napi\_delete\_callsite\_info、napi\_get\_property\_with\_callsite\_info、napi\_set\_property\_with\_callsite\_info**

[使用扩展的Node-API接口加速属性访问](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/use-napi-about-fast-property-access)