1# 使用Node-API接口进行object相关开发 2<!--Kit: NDK--> 3<!--Subsystem: arkcompiler--> 4<!--Owner: @xliu-huanwei; @shilei123; @huanghello--> 5<!--Designer: @shilei123--> 6<!--Tester: @kirl75; @zsw_zhushiwei--> 7<!--Adviser: @fang-jinxu--> 8 9## 简介 10 11Node-API提供了相关接口对object进行基本操作,例如创建对象、获取原型、冻结和密封对象,检查对象的类型等。 12 13## 基本概念 14 15在Node-API接口开发中,经常需要定义和操作对象。例如,创建一个API接口,该接口接受一个对象作为输入参数,对该对象执行某些操作,并返回一个结果对象。在这个过程中,需要确保接口的定义清晰、规范,并且与对象的属性和方法相兼容。 16 17- **接口(API)**:接口定义了组件之间的交互协议,包括输入参数、输出结果以及可能的错误处理。通过接口,组件可以相互调用和交换数据,而无需了解对方的内部实现细节。 18- **对象(Object)**:在ArkTS,对象是一种复合数据类型,允许存储多个不同类型的值作为一个单独的实体。对象是属性和方法的集合。属性是与对象相关联的值,而方法则是对象可以执行的操作。 19 20## 场景和功能介绍 21 22以下Node-API接口主要用于操作和管理ArkTS对象,使用场景介绍: 23| 接口 | 描述 | 24| -------- | -------- | 25| napi_get_prototype | 当需要获取一个ArkTS对象的原型时,可以使用这个接口。通过这个接口可以在C/C++中获取到这个原型对象。 | 26| napi_create_object | 在Node-API模块中创建一个默认的ArkTS对象。 | 27| napi_object_freeze | 当需要确保一个对象不会被修改时(immutable),可以使用这个接口来冻结该对象,使其属性不可更改。 | 28| napi_object_seal | 类似于napi_object_freeze,napi_object_seal用于密封给定的对象,使其属性不可添加或删除,但可以修改属性的值。 | 29| napi_typeof | 在处理传入的ArkTS值时,可以使用这个接口来获取其类型,以便进行相应的处理。 | 30| napi_instanceof | 当需要在Node-API模块中确定一个对象是否为特定构造函数的实例时,可以使用这个接口。 | 31| napi_type_tag_object | 可以将指针的特定值与ArkTS对象关联起来,这对于一些自定义的内部对象标记非常有用。 | 32| napi_check_object_type_tag | 使用此接口可以检查给定的对象上是否关联了特定类型的标记。 | 33| napi_create_symbol | 创建一个ArkTS Symbol对象。 | 34| napi_create_external | 用于创建一个ArkTS外部对象,该对象可以用于将C/C++中的自定义数据结构或对象传递到ArkTS中,并且可以在ArkTS中访问其属性和方法。 | 35| napi_get_value_external | 用于获得napi_create_external创建的绑定了外部数据的ArkTS值,此函数可以在ArkTS和C/C++之间传递数据。 | 36 37这些接口为开发人员提供了在Node-API模块中处理ArkTS对象的灵活性和功能性,可以实现从创建对象、管理对象属性和类型检查等多种操作。 38 39## 使用示例 40 41Node-API接口开发流程参考[使用Node-API实现跨语言交互开发流程](use-napi-process.md),本文仅对接口对应C++及ArkTS相关代码进行展示。 42 43### napi_get_prototype 44 45可以获得给定ArkTS对象的prototype。 46 47cpp部分代码 48 49```cpp 50#include "napi/native_api.h" 51 52static napi_value GetPrototype(napi_env env, napi_callback_info info) 53{ 54 // 获取并解析传参 55 size_t argc = 1; 56 napi_value args[1] = {nullptr}; 57 napi_get_cb_info(env, info, &argc, args , nullptr, nullptr); 58 napi_value result = nullptr; 59 // 获取此对象的原型对象,将结果返回到napi_value类型的变量result中 60 napi_get_prototype(env, args[0], &result); 61 return result; 62} 63``` 64<!-- @[napi_get_prototype](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/cpp/napi_init.cpp) --> 65 66接口声明 67 68```ts 69// index.d.ts 70export const getPrototype: (object: Object) => Object; 71``` 72<!-- @[napi_get_prototype_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/cpp/types/libentry/Index.d.ts) --> 73 74ArkTS侧示例代码 75 76```ts 77import { hilog } from '@kit.PerformanceAnalysisKit'; 78import testNapi from 'libentry.so'; 79// 定义一个类 80class Person { 81 // 属性 82 name: string; 83 age: number; 84 // 构造函数 85 constructor(name: string, age: number) { 86 this.name = name; 87 this.age = age; 88 } 89} 90// 创建类的实例 91const person = new Person('Alice', 30); 92// 传入实例对象,获取该对象的原型 93let applePrototype = testNapi.getPrototype(person); 94// 判断通过testNapi.getPrototype()函数获取到的原型是不是apple的原型 95// 在DevEco Studio 4.1及以后的版本中,由于ArkTS没有原型的概念,因此尝试进行原型赋值或相关操作时,将会触发错误提示'Prototype assignment is not supported (arkts-no-prototype-assignment)',以下代码需在ts文件中执行 96if (applePrototype === Person.prototype) { 97 hilog.info(0x0000, 'Node-API', 'get_prototype_success'); 98} else { 99 hilog.error(0x0000, 'Node-API', 'get_prototype_fail'); 100} 101``` 102<!-- @[ark_napi_get_prototype](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/ets/pages/napiGetPrototype.ts) --> 103 104### napi_create_object 105 106用于在Node-API模块中创建一个空的ArkTS对象。 107 108cpp部分代码 109 110```cpp 111#include "napi/native_api.h" 112 113napi_value NewObject(napi_env env, napi_callback_info info) 114{ 115 napi_value object = nullptr; 116 // 创建一个空对象 117 napi_create_object(env, &object); 118 // 设置对象的属性 119 napi_value name = nullptr; 120 // 设置属性名为"name" 121 napi_create_string_utf8(env, "name", NAPI_AUTO_LENGTH, &name); 122 napi_value value = nullptr; 123 // 设置属性值为"Hello from Node-API!" 124 napi_create_string_utf8(env, "Hello from Node-API!", NAPI_AUTO_LENGTH, &value); 125 // 将属性设置到对象上 126 napi_set_property(env, object, name, value); 127 return object; 128} 129``` 130<!-- @[napi_create_object](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/cpp/napi_init.cpp) --> 131 132接口声明 133 134```ts 135// index.d.ts 136export const createObject: () => { name: string }; 137``` 138<!-- @[napi_create_object_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/cpp/types/libentry/Index.d.ts) --> 139 140ArkTS侧示例代码 141 142```ts 143import { hilog } from '@kit.PerformanceAnalysisKit'; 144import testNapi from 'libentry.so'; 145try { 146 const myObject = testNapi.createObject(); 147 hilog.info(0x0000, 'testTag', 'Test Node-API napi_create_object: %{public}s', myObject.name); 148} catch (error) { 149 hilog.error(0x0000, 'testTag', 'Test Node-API napi_create_object errorCode: %{public}s, errorMessage: %{public}s', error.code, error.message); 150} 151``` 152<!-- @[ark_napi_create_object](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/ets/pages/Index.ets) --> 153 154### napi_object_freeze 155 156用于冻结给定的ArkTS对象。冻结对象后,无法再向对象添加新的属性或方法,也无法修改已有属性或方法的值。 157 158cpp部分代码 159 160```cpp 161#include "hilog/log.h" 162#include "napi/native_api.h" 163 164static napi_value ObjectFreeze(napi_env env, napi_callback_info info) 165{ 166 // 接受一个ArkTS侧传入的object 167 size_t argc = 1; 168 napi_value argv[1] = {nullptr}; 169 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 170 171 // 调用接口napi_object_freeze将传入的object冻结 172 napi_value objFreeze = argv[0]; 173 napi_status status = napi_object_freeze(env, objFreeze); 174 if (status == napi_ok) { 175 OH_LOG_INFO(LOG_APP, "Node-API napi_object_freeze success"); 176 } 177 // 将冻结后的object传回ArkTS侧 178 return objFreeze; 179} 180``` 181<!-- @[napi_object_freeze](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/cpp/napi_init.cpp) --> 182 183接口声明 184 185```ts 186// index.d.ts 187export interface Obj { 188 data: number 189 message: string 190} 191export const objectFreeze: (objFreeze: Object) => Obj; 192``` 193<!-- @[napi_object_freeze_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/cpp/types/libentry/Index.d.ts) --> 194 195ArkTS侧示例代码 196 197```ts 198import { hilog } from '@kit.PerformanceAnalysisKit'; 199import testNapi from 'libentry.so'; 200try { 201 class Obj { 202 data: number = 0 203 message: string = "" 204 } 205 let obj: Obj = {data: 0, message: "hello world"}; 206 let objFreeze = testNapi.objectFreeze(obj); 207 hilog.info(0x0000, 'testTag', 'Test Node-API napi_object_freeze: %{public}s', (objFreeze.data = 1)); 208} catch (error) { 209 hilog.error(0x0000, 'testTag', 'Test Node-API napi_object_freeze error: %{public}s', error.message); 210} 211``` 212<!-- @[ark_napi_object_freeze](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/ets/pages/Index.ets) --> 213 214### napi_object_seal 215 216封闭一个对象后,无法向其添加新的属性,也无法删除或修改现有属性的可配置性。但是,可以继续修改已有属性的值。 217 218cpp部分代码 219 220```cpp 221#include "hilog/log.h" 222#include "napi/native_api.h" 223 224static napi_value ObjectSeal(napi_env env, napi_callback_info info) 225{ 226 // 接受一个ArkTS侧传入的object 227 size_t argc = 1; 228 napi_value argv[1] = {nullptr}; 229 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); 230 // 调用接口napi_object_seal将传入的object封闭,使其无法添加新的属性 231 napi_value objSeal = argv[0]; 232 napi_status status = napi_object_seal(env, objSeal); 233 if (status == napi_ok) { 234 OH_LOG_INFO(LOG_APP, "Node-API napi_object_seal success"); 235 } else { 236 napi_throw_error(env, nullptr, "Node-API napi_object_seal failed"); 237 return nullptr; 238 } 239 // 将封闭后的object传回ArkTS侧 240 return objSeal; 241} 242``` 243<!-- @[napi_object_seal](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/cpp/napi_init.cpp) --> 244 245接口声明 246 247```ts 248// index.d.ts 249export interface Obj { 250 data: number 251 message: string 252 id: number 253} 254export const objectSeal : (objSeal: Object) => Obj; 255``` 256<!-- @[napi_object_seal_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/cpp/types/libentry/Index.d.ts) --> 257 258ArkTS侧示例代码 259 260```ts 261import { hilog } from '@kit.PerformanceAnalysisKit'; 262import testNapi from 'libentry.so'; 263try { 264 class Obj { 265 data: number = 0 266 message: string = "" 267 // 可选属性 268 address?: number 269 } 270 let obj: Obj = { data: 0, message: "hello world"}; 271 let objSeal = testNapi.objectSeal(obj); 272 hilog.info(0x0000, 'testTag', 'Test Node-API napi_object_seal: %{public}s', objSeal.message); 273 objSeal.data = 1; 274 hilog.info(0x0000, 'testTag', 'Test Node-API napi_object_seal: %{public}d', objSeal.data); 275 hilog.info(0x0000, 'testTag', 'Test Node-API napi_object_seal: %{public}d', (objSeal.id = 1)); 276} catch (error) { 277 hilog.error(0x0000, 'testTag', 'Test Node-API napi_object_seal error: %{public}s', error.message); 278} 279``` 280<!-- @[ark_napi_object_seal](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/ets/pages/Index.ets) --> 281 282### napi_typeof 283 284这个接口用于获取给定ArkTS value的ArkTS Type。 285 286**注:**napi_typeof可以判断的类型包含: 287undefined 288null 289boolean 290number 291string 292object 293function 294bigint 295 296cpp部分代码 297 298```cpp 299#include "napi/native_api.h" 300 301static napi_value NapiTypeOf(napi_env env, napi_callback_info info) 302{ 303 // 接受一个入参 304 size_t argc = 1; 305 napi_value args[1] = {nullptr}; 306 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 307 308 // 调用napi_typeof判断传入ArkTS参数类型 309 napi_valuetype valueType; 310 napi_status status = napi_typeof(env, args[0], &valueType); 311 if (status != napi_ok) { 312 napi_throw_error(env, nullptr, "Node-API napi_typeof fail"); 313 return nullptr; 314 } 315 // 将结果转成napi_value类型返回。 316 napi_value returnValue = nullptr; 317 switch(valueType) { 318 case napi_undefined: 319 napi_create_string_utf8(env, "Input type is napi_undefined", NAPI_AUTO_LENGTH, &returnValue); 320 break; 321 case napi_null: 322 napi_create_string_utf8(env, "Input type is napi_null", NAPI_AUTO_LENGTH, &returnValue); 323 break; 324 case napi_boolean: 325 napi_create_string_utf8(env, "Input type is napi_boolean", NAPI_AUTO_LENGTH, &returnValue); 326 break; 327 case napi_number: 328 napi_create_string_utf8(env, "Input type is napi_number", NAPI_AUTO_LENGTH, &returnValue); 329 break; 330 case napi_string: 331 napi_create_string_utf8(env, "Input type is napi_string", NAPI_AUTO_LENGTH, &returnValue); 332 break; 333 case napi_object: 334 napi_create_string_utf8(env, "Input type is napi_object", NAPI_AUTO_LENGTH, &returnValue); 335 break; 336 case napi_function: 337 napi_create_string_utf8(env, "Input type is napi_function", NAPI_AUTO_LENGTH, &returnValue); 338 break; 339 case napi_bigint: 340 napi_create_string_utf8(env, "Input type is napi_bigint", NAPI_AUTO_LENGTH, &returnValue); 341 break; 342 default: 343 napi_create_string_utf8(env, "unknown", NAPI_AUTO_LENGTH, &returnValue); 344 } 345 346 return returnValue; 347} 348``` 349<!-- @[napi_typeof](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/cpp/napi_init.cpp) --> 350 351接口声明 352 353```ts 354// index.d.ts 355export const napiTypeOf : <T>(value: T) => string | undefined; 356``` 357<!-- @[napi_typeof_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/cpp/types/libentry/Index.d.ts) --> 358 359ArkTS侧示例代码 360 361```ts 362import { hilog } from '@kit.PerformanceAnalysisKit'; 363import testNapi from 'libentry.so'; 364try { 365 let varUndefined: undefined; 366 hilog.info(0x0000, 'testTag', 'Test Node-API napi_typeof: %{public}s', testNapi.napiTypeOf(varUndefined)); 367 let varNull: null = null; 368 hilog.info(0x0000, 'testTag', 'Test Node-API napi_typeof: %{public}s', testNapi.napiTypeOf(varNull)); 369 let varTrue= true; 370 hilog.info(0x0000, 'testTag', 'Test Node-API napi_typeof: %{public}s', testNapi.napiTypeOf(varTrue)); 371 let varNum = 1; 372 hilog.info(0x0000, 'testTag', 'Test Node-API napi_typeof: %{public}s', testNapi.napiTypeOf(varNum)); 373 let varString = "str"; 374 hilog.info(0x0000, 'testTag', 'Test Node-API napi_typeof: %{public}s', testNapi.napiTypeOf(varString)); 375 class Obj { 376 id: number = 0 377 name: string = "" 378 } 379 let varObject: Obj = {id: 1, name: "LiLei"}; 380 hilog.info(0x0000, 'testTag', 'Test Node-API napi_typeof: %{public}s', testNapi.napiTypeOf(varObject)); 381 const mulNum = (a: number, b: number): number => a * b; 382 hilog.info(0x0000, 'testTag', 'Test Node-API napi_typeof: %{public}s', testNapi.napiTypeOf(mulNum)); 383 let varBigint = BigInt("1234567890123456789012345678901234567890"); 384 hilog.info(0x0000, 'testTag', 'Test Node-API napi_typeof: %{public}s', testNapi.napiTypeOf(varBigint)); 385} catch (error) { 386 hilog.error(0x0000, 'testTag', 'Test Node-API napi_typeof error: %{public}s', error.message); 387} 388``` 389<!-- @[ark_napi_typeof](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/ets/pages/Index.ets) --> 390 391### napi_instanceof 392 393用于检查一个对象是否是指定构造函数的实例。 394 395cpp部分代码 396 397```cpp 398#include "napi/native_api.h" 399 400static napi_value NapiInstanceOf(napi_env env, napi_callback_info info) 401{ 402 // 接受两个入参 403 size_t argc = 2; 404 napi_value args[2] = {nullptr}; 405 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 406 // 调用napi_instanceof接口判断给定object是否为给定constructor的实例 407 bool result = true; 408 napi_status status = napi_instanceof(env, args[0], args[1], &result); 409 if (status != napi_ok) { 410 napi_throw_error(env, nullptr, "Node-API napi_instanceof fail"); 411 return nullptr; 412 } 413 // 将结果转成napi_value类型返回 414 napi_value returnValue = nullptr; 415 napi_get_boolean(env, result, &returnValue); 416 417 return returnValue; 418} 419``` 420<!-- @[napi_instanceof](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/cpp/napi_init.cpp) --> 421 422接口声明 423 424```ts 425// index.d.ts 426export const napiInstanceOf: (date: Object, construct: Object) => boolean | undefined; 427``` 428<!-- @[napi_instanceof_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/cpp/types/libentry/Index.d.ts) --> 429 430ArkTS侧示例代码 431 432```ts 433import { hilog } from '@kit.PerformanceAnalysisKit'; 434import testNapi from 'libentry.so'; 435try { 436 class Person { 437 name: string; 438 age: number; 439 440 constructor(name: string, age: number) { 441 this.name = name; 442 this.age = age; 443 } 444 } 445 const person = new Person("Alice", 30); 446 class Obj { 447 data: number = 0 448 message: string = "" 449 } 450 let obj: Obj = { data: 0, message: "hello world"}; 451 hilog.info(0x0000, 'testTag', 'Test Node-API napi_instanceof: %{public}s', testNapi.napiInstanceOf(person, Person)); 452 hilog.info(0x0000, 'testTag', 'Test Node-API napi_instanceof: %{public}s', testNapi.napiInstanceOf(obj, Person)); 453} catch (error) { 454 hilog.error(0x0000, 'testTag', 'Test Node-API napi_instanceof error: %{public}s', error.message); 455} 456``` 457<!-- @[ark_napi_instanceof](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/ets/pages/Index.ets) --> 458 459### napi_type_tag_object 460 461使用类型标签type_tag来标记ArkTS对象,后续可以更精确地识别ArkTS对象。 462 463### napi_check_object_type_tag 464 465验证一个ArkTS对象是否带有特定类型标签。 466 467类型标签提供了一种在Node-API模块和ArkTS对象之间建立强类型关联的机制,使得原生代码能够更准确地识别和处理特定的ArkTS对象。 468 469cpp部分代码 470 471```cpp 472#include "napi/native_api.h" 473 474#define NUMBERINT_FOUR 4 475// 定义一个静态常量napi_type_tag数组存储类型标签 476static const napi_type_tag TagsData[NUMBERINT_FOUR] = { 477 {0x9e4b2449547061b3, 0x33999f8a6516c499}, 478 {0x1d55a794c53a726d, 0x43633f509f9c944e}, 479 // 用于表示无标签或默认标签 480 {0, 0}, 481 {0x6a971439f5b2e5d7, 0x531dc28a7e5317c0}, 482}; 483 484static napi_value SetTypeTagToObject(napi_env env, napi_callback_info info) 485{ 486 // 获取函数调用信息和参数 487 size_t argc = 2; 488 napi_value args[2] = {nullptr}; 489 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 490 // 获取索引数字转换为napi_value 491 int32_t index = 0; 492 napi_get_value_int32(env, args[1], &index); 493 // 给参数(对象)设置类型标签 494 napi_status status = napi_type_tag_object(env, args[0], &TagsData[index]); 495 if (status != napi_ok) { 496 napi_throw_error(env, "Reconnect error", "napi_type_tag_object failed"); 497 return nullptr; 498 } 499 // 将bool结果转换为napi_value并返回 500 napi_value result = nullptr; 501 napi_get_boolean(env, true, &result); 502 return result; 503} 504 505static napi_value CheckObjectTypeTag(napi_env env, napi_callback_info info) 506{ 507 // 获取函数调用信息和参数 508 size_t argc = 2; 509 napi_value args[2] = {nullptr}; 510 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 511 // 获取索引数字转换为napi_value 512 int32_t index = 0; 513 napi_get_value_int32(env, args[1], &index); 514 // 检查对象的类型标签 515 bool checkResult = true; 516 napi_check_object_type_tag(env, args[0], &TagsData[index], &checkResult); 517 // 将bool结果转换为napi_value并返回 518 napi_value checked = nullptr; 519 napi_get_boolean(env, checkResult, &checked); 520 521 return checked; 522} 523``` 524<!-- @[napi_type_tag_object](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/cpp/napi_init.cpp) --> 525 526接口声明 527 528```ts 529// index.d.ts 530export const setTypeTagToObject: (obj: Object, index: number) => boolean | undefined; 531export const checkObjectTypeTag: (obj: Object, index: number) => boolean; 532``` 533<!-- @[napi_type_tag_object_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/cpp/types/libentry/Index.d.ts) --> 534 535ArkTS侧示例代码 536 537```ts 538import { hilog } from '@kit.PerformanceAnalysisKit'; 539import testNapi from 'libentry.so'; 540class Obj { 541 data: number = 0 542 message: string = "" 543} 544let objA: Obj = { data: 0, message: "hello world"}; 545let objB: Obj = { data: 10, message: "typeTag"}; 546hilog.info(0x0000, 'testTag', 'Test Node-API napi_type_tag_object objA -> 0: %{public}s', testNapi.setTypeTagToObject(objA, 0)); 547hilog.info(0x0000, 'testTag', 'Test Node-API napi_type_tag_object objB -> 0: %{public}s', testNapi.setTypeTagToObject(objB, 0)); 548hilog.info(0x0000, 'testTag', 'Test Node-API napi_check_object_type_tag objA -> 0: %{public}s', testNapi.checkObjectTypeTag(objA, 0)); 549hilog.info(0x0000, 'testTag', 'Test Node-API napi_check_object_type_tag objB -> 1: %{public}s', testNapi.checkObjectTypeTag(objB, 1)); 550``` 551<!-- @[ark_napi_type_tag_object](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/ets/pages/Index.ets) --> 552 553### napi_create_external 554 555创建自定义的C/C++对象并将其公开给ArkTS代码。这种情况下,我们可以使用napi_create_external来创建一个包含指向自定义对象的指针的Node-API值,以便让ArkTS代码能够访问和操作该对象。 556 557cpp部分代码 558 559```cpp 560#include <cstdlib> 561#include <string> 562#include "hilog/log.h" 563#include "napi/native_api.h" 564 565// 用于释放外部数据的回调函数 566void finalizeCallback(napi_env env, void *data, void *hint) { 567 // 释放外部数据 568 free(data); 569} 570 571static napi_value GetExternalType(napi_env env, napi_callback_info info) 572{ 573 size_t argc = 1; 574 napi_value args[1] = {nullptr}; 575 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 576 // 获取参数的数据类型 577 napi_valuetype valueType; 578 napi_typeof(env, args[0], &valueType); 579 napi_value returnValue = nullptr; 580 if (valueType == napi_external) { 581 // 如果数据类型是napi_external,则返回true 582 napi_get_boolean(env, true, &returnValue); 583 } else { 584 napi_get_boolean(env, false, &returnValue); 585 } 586 return returnValue; 587} 588 589static napi_value CreateExternal(napi_env env, napi_callback_info info) 590{ 591 // 设置外部数据大小为10 592 const size_t dataSize = 10; 593 // 分配外部数据 594 void *data = malloc(dataSize); 595 if (data == nullptr) { 596 OH_LOG_ERROR(LOG_APP, "malloc failed"); 597 return nullptr; 598 } 599 // 初始化外部数据 600 memset(data, 0, dataSize); 601 napi_value result = nullptr; 602 // 返回带有外部数据的对象 603 napi_status status = napi_create_external(env, data, finalizeCallback, nullptr, &result); 604 if (status != napi_ok) { 605 OH_LOG_ERROR(LOG_APP, " Node-API Failed to create external data"); 606 return nullptr; 607 } 608 return result; 609} 610``` 611<!-- @[napi_create_external](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/cpp/napi_init.cpp) --> 612 613接口声明 614 615```ts 616// index.d.ts 617export const createExternal: () => Object; 618export const getExternalType: (externalData: Object) => boolean; 619``` 620<!-- @[napi_create_external_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/cpp/types/libentry/Index.d.ts) --> 621 622ArkTS侧示例代码 623 624```ts 625import { hilog } from '@kit.PerformanceAnalysisKit'; 626import testNapi from 'libentry.so'; 627const externalData = testNapi.createExternal(); 628hilog.info(0x0000, 'testTag', 'Test Node-API napi_create_external:%{public}s', testNapi.getExternalType(externalData)); 629``` 630<!-- @[ark_napi_create_external](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/ets/pages/Index.ets) --> 631 632### napi_get_value_external 633 634napi_create_external可以创建包装自定义的C/C++对象并将其公开给ArkTS代码,而napi_get_value_external就是用来获得napi_create_external所创建的外部对象的。 635 636cpp部分代码 637 638```cpp 639#include "napi/native_api.h" 640 641static int external = 5; 642static napi_value GetValueExternal(napi_env env, napi_callback_info info) 643{ 644 // 创建外部数据 645 int* data = &external; 646 napi_value setExternal = nullptr; 647 napi_create_external(env, data, nullptr, nullptr, &setExternal); 648 // 获得外部数据的值 649 void *getExternal; 650 napi_get_value_external(env, setExternal, &getExternal); 651 // 返回获得到的外部数据 652 napi_value result = nullptr; 653 napi_create_int32(env, *(int *)getExternal, &result); 654 return result; 655} 656``` 657<!-- @[napi_get_value_external](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/cpp/napi_init.cpp) --> 658 659接口声明 660 661```ts 662// index.d.ts 663export const getValueExternal: () => number; 664``` 665<!-- @[napi_get_value_external_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/cpp/types/libentry/Index.d.ts) --> 666 667ArkTS侧示例代码 668 669```ts 670import { hilog } from '@kit.PerformanceAnalysisKit'; 671import testNapi from 'libentry.so'; 672hilog.info(0x0000, 'Node-API', 'get_value_external:%{public}d', testNapi.getValueExternal()); 673``` 674<!-- @[ark_napi_get_value_external](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/ets/pages/Index.ets) --> 675 676### napi_create_symbol 677 678用于创建一个新的Symbol。Symbol是一种特殊的数据类型,用于表示唯一的标识符。与字符串或数字不同,符号的值是唯一的,即使两个符号具有相同的描述,它们也是不相等的。符号通常用作对象属性的键,以确保属性的唯一性。 679 680cpp部分代码 681 682```cpp 683#include "napi/native_api.h" 684#include "hilog/log.h" 685 686static napi_value CreateSymbol(napi_env env, napi_callback_info info) 687{ 688 napi_value result = nullptr; 689 const char *des = "only"; 690 // 使用napi_create_string_utf8创建描述字符串 691 napi_status status = napi_create_string_utf8(env, des, NAPI_AUTO_LENGTH, &result); 692 if (status != napi_ok) { 693 OH_LOG_ERROR(LOG_APP, "Node-API napi_create_string_utf8 failed"); 694 return nullptr; 695 } 696 napi_value returnSymbol = nullptr; 697 // 创建一个symbol类型,并返回 698 status = napi_create_symbol(env, result, &returnSymbol); 699 if (status != napi_ok) { 700 OH_LOG_ERROR(LOG_APP, "Node-API napi_create_symbol failed"); 701 return nullptr; 702 } 703 return returnSymbol; 704} 705``` 706<!-- @[napi_create_symbol](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/cpp/napi_init.cpp) --> 707 708接口声明 709 710```ts 711// index.d.ts 712export const createSymbol : () => symbol; 713``` 714<!-- @[napi_create_symbol_api](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/cpp/types/libentry/Index.d.ts) --> 715 716ArkTS侧示例代码 717 718```ts 719import { hilog } from '@kit.PerformanceAnalysisKit'; 720import testNapi from 'libentry.so'; 721let varSymbol = testNapi.createSymbol(); 722hilog.info(0x0000, 'Node-API', 'createSymbol:%{public}s', typeof varSymbol); 723``` 724<!-- @[ark_napi_create_symbol](https://gitcode.com/openharmony/applications_app_samples/blob/master/code/DocsSample/ArkTS/NodeAPI/NodeAPIUse/NodeAPIObject/entry/src/main/ets/pages/Index.ets) --> 725 726以上代码如果要在native cpp中打印日志,需在CMakeLists.txt文件中添加以下配置信息(并添加头文件:#include "hilog/log.h"): 727 728```text 729// CMakeLists.txt 730add_definitions( "-DLOG_DOMAIN=0xd0d0" ) 731add_definitions( "-DLOG_TAG=\"testTag\"" ) 732target_link_libraries(entry PUBLIC libace_napi.z.so libhilog_ndk.z.so) 733``` 734