使用Node-API接口关联数据，使其生命周期与当前环境的生命周期相关联
====================================

#### 简介

在Node-API模块中，可以使用Node-API接口将特定数据与当前环境相关联，并在需要时检索该数据。

#### 基本概念

在Node-API中，关联数据指的是将自定义的C++数据结构与当前环境的生命周期绑定，这意味着只要当前运行环境存在，关联数据就会保持有效。

#### 场景和功能介绍

以下接口可在Node-API模块中更方便地管理对象实例所需的状态信息、引用计数或其他自定义数据，它们的使用场景如下：

| 接口 | 描述 |
| :-- | :-- |
| napi\_set\_instance\_data | 绑定与当前运行的环境相关联的数据项。 |
| napi\_get\_instance\_data | 检索与当前运行的环境相关联的数据项。 |

#### 使用示例

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

#### \[h2\]napi\_set\_instance\_data

将需要绑定的数据与当前运行的环境相关联。

cpp部分代码

#include "napi/native\_api.h"

// 定义一个结构来存储实例数据
struct InstanceData {
    int32\_t value;
};

// 对象被释放时的回调函数，用于清理实例数据
void FinalizeCallback(napi\_env env, void \*finalizeData, void \*finalizeHint)
{
    if (finalizeData) {
        InstanceData \*data = reinterpret\_cast<InstanceData \*>(finalizeData);
        // 释放内存，清除指针指向地址
        delete (data);
    }
}

// napi\_set\_instance\_data
static napi\_value SetInstanceData(napi\_env env, napi\_callback\_info info)
{
    size\_t argc = 1;
    napi\_value argv\[1\];
    napi\_get\_cb\_info(env, info, &argc, argv, nullptr, nullptr);
    int32\_t instanceDataValue;
    napi\_get\_value\_int32(env, argv\[0\], &instanceDataValue);
    InstanceData \*instanceData = new InstanceData;
    instanceData->value = instanceDataValue;
    // 调用napi\_set\_instance\_data将实例数据关联到Node-API环境，并指定FinalizeCallback函数
    napi\_status status = napi\_set\_instance\_data(env, instanceData, FinalizeCallback, nullptr);
    if (status != napi\_ok) {
        delete instanceData;
        napi\_throw\_error(env, nullptr, "Test Node-API napi\_set\_instance\_data failed");
        return nullptr;
    }
    bool success = true;
    napi\_value result = nullptr;
    napi\_get\_boolean(env, success, &result);
    return result;
}

接口声明

export const setInstanceData: (data: number) => boolean | undefined; // napi\_set\_instance\_data

ArkTS侧示例代码

// napi\_set\_instance\_data
let data = 5;
let value = testNapi.setInstanceData(data);
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_set\_instance\_data:%{public}s', value);

#### \[h2\]napi\_get\_instance\_data

检索与当前运行的环境相关联的数据项。

cpp部分代码

// napi\_get\_instance\_data
static napi\_value GetInstanceData(napi\_env env, napi\_callback\_info info)
{
    InstanceData \*resData = nullptr;
    // napi\_get\_instance\_data获取之前相关联的数据项
    napi\_status status = napi\_get\_instance\_data(env, (void \*\*)&resData);
    if (status != napi\_ok) {
        return nullptr;
    }

    if (resData == nullptr) {
        napi\_throw\_error(env, nullptr, "Instance data not set or already freed");
        return nullptr;
    }
    napi\_value result = nullptr;
    napi\_create\_int32(env, resData->value, &result);
    return result;
}

接口声明

export const getInstanceData: () => number | undefined; // napi\_get\_instance\_data

ArkTS侧示例代码

// napi\_get\_instance\_data
let data = 5;
testNapi.setInstanceData(data);
let value = testNapi.getInstanceData();
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_set\_instance\_data:%{public}d', value);

以上代码如果要在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)