1# 使用Node-API接口关联数据,使其生命周期与当前环境的生命周期相关联
2
3## 简介
4
5在Node-API模块中,我们可以使用Node-API接口将特定数据与当前的环境相关联,并在需要时检索该数据。
6
7## 基本概念
8
9在Node-API中的关联数据是指将自定义的C++数据结构的生命周期与当前环境的生命周期相关联,这意味着只要当前运行环境存在,关联数据就会保持有效。
10
11## 场景和功能介绍
12
13以下接口可以帮助我们在Node-API模块中更方便地管理对象实例所需的状态信息、引用计数或其他自定义数据,他们的使用场景如下:
14| 接口 | 描述 |
15| -------- | -------- |
16| napi_set_instance_data | 绑定与当前运行的环境相关联的数据项。 |
17| napi_get_instance_data | 检索与当前运行的环境相关联的数据项。 |
18
19## 使用示例
20
21Node-API接口开发流程参考[使用Node-API实现跨语言交互开发流程](use-napi-process.md),本文仅对接口对应C++及ArkTS相关代码进行展示。
22
23### napi_set_instance_data
24
25将需要绑定的数据与当前运行的环境相关联。
26
27cpp部分代码
28
29```cpp
30#include <cstdlib>
31#include "napi/native_api.h"
32
33// 定义一个结构来存储实例数据
34struct InstanceData {
35    int32_t value;
36};
37
38// 对象被释放时的回调函数,用于清理实例数据
39void FinalizeCallback(napi_env env, void *finalize_data, void *finalize_hint)
40{
41    if (finalize_data) {
42        InstanceData *data = reinterpret_cast<InstanceData *>(finalize_data);
43        // 释放内存,清除指针指向地址
44        delete (data);
45        *(InstanceData **)finalize_data = nullptr;
46    }
47}
48
49static napi_value SetInstanceData(napi_env env, napi_callback_info info)
50{
51    size_t argc = 1;
52    napi_value argv[1];
53    napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
54    int32_t instanceDataValue;
55    napi_get_value_int32(env, argv[0], &instanceDataValue);
56    InstanceData *instanceData = new InstanceData;
57    instanceData->value = instanceDataValue;
58    // 调用napi_set_instance_data将实例数据关联到Node-API环境,并指定FinalizeCallback函数
59    napi_status status = napi_set_instance_data(env, instanceData, FinalizeCallback, nullptr);
60    bool success = true;
61    napi_value result;
62    if (status == napi_ok) {
63        napi_get_boolean(env, success, &result);
64    }
65    return result;
66}
67```
68
69接口声明
70
71```ts
72// index.d.ts
73export const setInstanceData: (data: number) => boolean;
74```
75
76ArkTS侧示例代码
77
78```ts
79import hilog from '@ohos.hilog'
80import testNapi from 'libentry.so'
81let data = 5;
82let value = testNapi.setInstanceData(data);
83hilog.info(0x0000, 'testTag', 'Test Node-API napi_set_instance_data:%{public}s', value);
84```
85
86### napi_get_instance_data
87
88检索出与当前运行的环境相关联的数据项。
89
90cpp部分代码
91
92```cpp
93#include "napi/native_api.h"
94
95static napi_value GetInstanceData(napi_env env, napi_callback_info info) {
96    InstanceData *resData = nullptr;
97    // napi_get_instance_data获取之前想关联的数据项
98    napi_get_instance_data(env, (void **)&resData);
99    napi_value result;
100    napi_create_int32(env, resData->value, &result);
101    return result;
102}
103```
104
105接口声明
106
107```ts
108// index.d.ts
109export const getInstanceData: () => number;
110```
111
112ArkTS侧示例代码
113
114```ts
115import hilog from '@ohos.hilog'
116import testNapi from 'libentry.so'
117let data = 5;
118testNapi.setInstanceData(data);
119let value = testNapi.getInstanceData();
120hilog.info(0x0000, 'testTag', 'Test Node-API napi_set_instance_data:%{public}d', value);
121```
122
123以上代码如果要在native cpp中打印日志,需在CMakeLists.txt文件中添加以下配置信息(并添加头文件:#include "hilog/log.h"):
124
125```text
126// CMakeLists.txt
127add_definitions( "-DLOG_DOMAIN=0xd0d0" )
128add_definitions( "-DLOG_TAG=\"testTag\"" )
129target_link_libraries(entry PUBLIC libhilog_ndk.z.so)
130```
131