使用Node-API接口进行primitive类相关开发
============================

#### 简介

使用Node-API接口，开发人员可以在Node-API模块中与ArkTS对象交互，进行数据转换和获取特定对象。这些操作在不同场景中发挥重要作用，使开发人员能够更灵活地处理ArkTS值和对象。

#### 基本概念

使用Node-API操作ArkTS对象时，需要了解一些基本概念。

*   **ArkTS值到C/C++类型的转换：** 在Node-API模块中，可以使用Node-API函数将ArkTS值转换为C/C++的数据类型，如将ArkTS数值转换为C/C++的整数、将ArkTS字符串转换为C/C++的字符数组等。同样，也可以将C/C++的数据类型转换为ArkTS值，以便将结果返回给ArkTS代码。

#### 场景和功能介绍

以下接口用于从C/C++代码中与ArkTS交互，传递数据并执行操作

| 接口 | 描述 |
| :-- | :-- |
| napi\_coerce\_to\_bool | 将给定的ArkTS value强转为ArkTS boolean值。 |
| napi\_coerce\_to\_number | 将给定的ArkTS value强转成ArkTS number。 |
| napi\_coerce\_to\_object | 将给定的ArkTS value强转成ArkTS Object。 |
| napi\_coerce\_to\_string | 将给定的ArkTS value强转成ArkTS string。 |
| napi\_get\_boolean | 将给定的C boolean值，获取ArkTS boolean值。 |
| napi\_get\_value\_bool | 根据给定的ArkTS boolean值，获取等价的C/C++布尔值。 |
| napi\_get\_global | 获取全局ArkTS对象，以便在C/C++中访问和操纵全局对象。 |
| napi\_get\_null | 获取ArkTS null。 |
| napi\_get\_undefined | 获取ArkTS undefined。 |

#### 使用示例

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

#### \[h2\]napi\_coerce\_to\_bool

用于将给定的ArkTS value强转成ArkTS boolean值。

cpp部分代码

// napi\_coerce\_to\_bool
static napi\_value CoerceToBool(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);
    // 将传入的值转换为布尔值
    napi\_value result = nullptr;
    napi\_coerce\_to\_bool(env, args\[0\], &result);
    // 返回强转之后的ArkTS boolean值
    return result;
}

接口声明

export const coerceToBool: <T>(data: T) => boolean; // napi\_coerce\_to\_bool

ArkTS侧示例代码

// napi\_coerce\_to\_bool
let value = testNapi.coerceToBool<number>(0);
let str = testNapi.coerceToBool<string>('111111111');
let obj = new Object();
let res = testNapi.coerceToBool<Object>(obj);
let result = testNapi.coerceToBool<null>(null);
// false
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_coerce\_to\_bool:%{public}s', value);
// true
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_coerce\_to\_bool:%{public}s', str);
// true
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_coerce\_to\_bool:%{public}s', res);
// false
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_coerce\_to\_bool:%{public}s', result);

#### \[h2\]napi\_coerce\_to\_number

将给定的ArkTS value强转成ArkTS number。

cpp部分代码

// napi\_coerce\_to\_number
static napi\_value CoerceToNumber(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);
    // 将传入的值转换为number值
    napi\_value result = nullptr;
    napi\_coerce\_to\_number(env, args\[0\], &result);
    return result;
}

接口声明

export const coerceToNumber: <T>(data: T) => number; // napi\_coerce\_to\_number

ArkTS侧示例代码

// napi\_coerce\_to\_number
let value = testNapi.coerceToNumber<string>('2556');
let str = testNapi.coerceToNumber<string>('sssss');
let bool = testNapi.coerceToNumber<boolean>(true);
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_coerce\_to\_number:%{public}d', value);
// 返回的为NAN
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_coerce\_to\_number:%{public}d', str);
// 返回的是1
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_coerce\_to\_number:%{public}d', bool);

#### \[h2\]napi\_coerce\_to\_object

用于将给定的ArkTS value强转成ArkTS Object。

cpp部分代码：

// napi\_coerce\_to\_object
static napi\_value CoerceToObject(napi\_env env, napi\_callback\_info info)
{
    // 获取并解析传入的参数
    size\_t argc = 1;
    napi\_value args\[1\] = {nullptr};
    napi\_value obj = nullptr;
    napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr);
    // 将传入的值转换为Object值
    napi\_coerce\_to\_object(env, args\[0\], &obj);
    return obj;
}

接口声明

export const coerceToObject: <T>(data: T) => Object; // napi\_coerce\_to\_object

ArkTS侧示例代码

// napi\_coerce\_to\_object
let value = testNapi.coerceToObject<string>('222222');
let result = testNapi.coerceToObject<number>(111);
hilog.info(0x0000, 'testTag', 'Node-API coerceToObject:%{public}s.', typeof result);
if (typeof value === 'object') {
  hilog.info(0x0000, 'testTag', 'Node-API The value is an object.');
} else {
  hilog.info(0x0000, 'testTag', 'Node-API The value is not an object.');
}

#### \[h2\]napi\_coerce\_to\_string

用于将给定的ArkTS value强转成ArkTS string。

cpp部分代码

// napi\_coerce\_to\_string
static napi\_value CoerceToString(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);
    // 将传入的值转换为string
    napi\_value str = nullptr;
    napi\_coerce\_to\_string(env, args\[0\], &str);
    return str;
}

接口声明

export const coerceToString: <T>(data: T) => string; // napi\_coerce\_to\_string

ArkTS侧示例代码

// napi\_coerce\_to\_string
let value = testNapi.coerceToString<number>(212);
let obj = new Object();
let res = testNapi.coerceToString<Object>(obj);
let bool = testNapi.coerceToString<boolean>(false);
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_coerce\_to\_string:%{public}s', value);
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_coerce\_to\_string:%{public}s', typeof res);
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_coerce\_to\_string:%{public}s', bool);

#### \[h2\]napi\_get\_boolean

根据给定的C boolean值，获取等价的ArkTS boolean值。

cpp部分代码

// napi\_get\_boolean
static napi\_value GetBoolean(napi\_env env, napi\_callback\_info info)
{
    // 传入两个参数并解析
    size\_t argc = 2;
    napi\_value argv\[2\];
    napi\_valuetype data = napi\_undefined;
    napi\_valuetype value = napi\_undefined;
    napi\_status status = napi\_get\_cb\_info(env, info, &argc, argv, nullptr, nullptr);
    if (status != napi\_ok) {
        OH\_LOG\_ERROR(LOG\_APP, "napi\_get\_cb\_info failed");
        return nullptr;
    }
    // 判断两个参数类型值
    napi\_typeof(env, argv\[0\], &data);
    napi\_typeof(env, argv\[1\], &value);

    napi\_value returnValue = nullptr;
    // 判断两个类型值是否相等,获取结果的布尔值
    status = napi\_get\_boolean(env, data == value, &returnValue);
    if (status != napi\_ok) {
        OH\_LOG\_ERROR(LOG\_APP, "napi\_get\_boolean failed");
        return nullptr;
    }
    // 返回结果
    return returnValue;
}

接口声明

export const getBoolean: <T>(data: T, value: String) => boolean; // napi\_get\_boolean

ArkTS侧示例代码

// napi\_get\_boolean
let value = testNapi.getBoolean<number>(1, '1');
let data = testNapi.getBoolean<string>('sss', '1');
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_get\_boolean:%{public}s', value);
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_get\_boolean:%{public}s', data);

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

使用此函数将ArkTS中的布尔值转换为等价的C布尔值。

cpp部分代码

// napi\_get\_value\_bool
static napi\_value GetValueBool(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 boolC = false;
    napi\_status status = napi\_get\_value\_bool(env, args\[0\], &boolC);
    if (status == napi\_boolean\_expected) {
        // 如果napi\_get\_value\_bool成功会返回napi\_ok，如果传入一个非布尔值则会返回napi\_boolean\_expected
        return nullptr;
    }
    napi\_value boolNapi = nullptr;
    status = napi\_get\_boolean(env, boolC, &boolNapi);
    if (status != napi\_ok) {
        OH\_LOG\_ERROR(LOG\_APP, "napi\_get\_boolean failed");
        return nullptr;
    }
    return boolNapi;
}

接口声明

export const getValueBool: (value: boolean | string) => boolean | undefined; // napi\_get\_value\_bool

ArkTS侧示例代码

// napi\_get\_value\_bool
// 分别传入布尔值和非布尔值检测接口,传入布尔值将返回原布尔值,传入其他类型返回undefined
hilog.info(0x0000, 'Node-API', 'get\_value\_bool\_not\_bool %{public}s',
  testNapi.getValueBool('你好123'));
hilog.info(0x0000, 'Node-API', 'get\_value\_bool\_true %{public}s', testNapi.getValueBool(true));
hilog.info(0x0000, 'Node-API', 'get\_value\_bool\_false %{public}s', testNapi.getValueBool(false));

#### \[h2\]napi\_get\_global

获取全局ArkTS对象。此函数用于获取表示ArkTS全局对象的napi\_value，使C/C++模块能与ArkTS运行时的全局对象交互。

cpp部分代码

// napi\_get\_global
static napi\_value GetGlobal(napi\_env env, napi\_callback\_info info)
{
    napi\_value global = nullptr;
    // 获取global对象
    napi\_get\_global(env, &global);
    return global;
}

接口声明

export const getGlobal: () => Object; // napi\_get\_global

ArkTS侧示例代码

// napi\_get\_global
let globalObj = testNapi.getGlobal();
// 判断获取的global是否具有global的自身属性
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_get\_global:%{public}s',
  globalObj.hasOwnProperty!("undefined"));

#### \[h2\]napi\_get\_null

获取ArkTS中的null值。

cpp部分代码

// napi\_get\_null
static napi\_value GetNull(napi\_env env, napi\_callback\_info info)
{
    napi\_value nullValue = nullptr;
    napi\_get\_null(env, &nullValue);
    return nullValue;
}

接口声明

export const getNull: () => null; // napi\_get\_null

ArkTS侧示例代码

// napi\_get\_null
let value = testNapi.getNull();
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_get\_null:%{public}s', value);

#### \[h2\]napi\_get\_undefined

获取ArkTS中的undefined值。

cpp部分代码

// napi\_get\_undefined
static napi\_value GetUndefined(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);

    napi\_value value = nullptr;
    napi\_get\_undefined(env, &value);
    // 判断传入参数的类型与undefined值的类型是否一致
    bool isEqual = false;
    napi\_strict\_equals(env, args\[0\], value, &isEqual);
    // 参数与undefined值相等
    napi\_value result = nullptr;
    // 返回判断类型之后的结果，相等返回为true，不等则为false
    napi\_get\_boolean(env, isEqual, &result);
    return result;
}

接口声明

export const getUndefined: (value: undefined) => boolean; // napi\_get\_undefined

ArkTS侧示例代码

// napi\_get\_undefined
let data: undefined = undefined;
let value = testNapi.getUndefined(data);
hilog.info(0x0000, 'testTag', 'Test Node-API napi\_get\_undefined:%{public}s', 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)