鸿蒙 Node-API 自用整理

内容可能存在错误,也可能由于版本更新存在差异;请各位大佬自行甄别;

napi_status napi_get_cb_info

arduino 复制代码
napi_status napi_get_cb_info(
    napi_env env,
    napi_callback_info cbinfo,
    size_t* argc,
    napi_value* argv,
    napi_value* thisArg,
    void** data
);
参数含义
参数 方向 类型 说明
env in napi_env 当前 NAPI 执行环境上下文,所有 NAPI 方法都需要传递此参数
cbinfo in napi_callback_info 回调信息对象,由 Node-API 在调用原生函数时自动传入
argc in-out size_t* 输入时 :表示期望接收的最大参数数量 输出时 :表示实际传入的参数数量 可传 nullptr 忽略
argv out napi_value* 存储参数的数组,需预先分配足够内存 可传 nullptr 忽略
thisArg out napi_value* 接收函数调用时的 this 对象 可传 nullptr 忽略
data out void** 接收通过 napi_create_function 绑定的自定义数据 可传 nullptr 忽略

在平时的调用中一般仅仅设置前4个值;剩余两个传递nullptr 即可;

如果调用该方法时不知道参数个数;可以设置期望值是0;然后再执行完api 后argc 就会得到真实的参数个数;注意:这个时候不用设置对应的 argv,直接传递 nullptr即可;因为当前还不知道固定参数的大小;

目的:在 TS 调用传递参数到 native 层的时候;用于对参数个数,以及参数进行接收;用于后面的使用做准备;一般用于第一步执行逻辑;

返回值:napi_status 用于判断结果是否正确;判断逻辑如下:

kotlin 复制代码
    if (status != napi_ok || argc < 1)// argc 是对应的参数个数;设置了一个参数判断几个
    {
        return "";//根据条件进行返回
    }

动态的获取参数数据:

arduino 复制代码
#include "napi/native_api.h"

static napi_value DynamicTypeDemo(napi_env env, napi_callback_info info) {
    // 1. 先获取参数数量
    size_t argc = 0;
    napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);

    if (argc == 0) {
        return nullptr;
    }

    // 2. 动态分配数组并获取参数
    napi_value* args = new napi_value[argc];
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    // 3. 遍历每个参数,动态判断类型
    for (size_t i = 0; i < argc; i++) {
        napi_valuetype type;
        napi_typeof(env, args[i], &type);

        switch (type) {
            case napi_undefined:
                // 处理 undefined 类型
                break;
            case napi_null:
                // 处理 null 类型
                break;
            case napi_boolean:
                // 处理 boolean 类型
                bool boolValue;
                napi_get_value_bool(env, args[i], &boolValue);
                break;
            case napi_number:
                // 处理 number 类型
                double numValue;
                napi_get_value_double(env, args[i], &numValue);
                break;
            case napi_string:
                // 处理 string 类型
                size_t strLen;
                napi_get_value_string_utf8(env, args[i], nullptr, 0, &strLen);
                // ... 获取字符串内容
                break;
            case napi_object:
                // 处理 object 类型
                // 可进一步判断是否为数组
                bool isArray;
                napi_is_array(env, args[i], &isArray);
                break;
            case napi_function:
                // 处理 function 类型(回调函数)
                break;
            default:
                break;
        }
    }

    delete[] args;
    return nullptr;
}

获取 this 对象模式:

arduino 复制代码
static napi_value GetThisDemo(napi_env env, napi_callback_info info) {
    size_t argc = 0;
    napi_value thisArg = nullptr;
    napi_get_cb_info(env, info, &argc, nullptr, &thisArg, nullptr);

    // thisArg 即为调用该方法的对象
    return thisArg;
}

注意:这个对象获取的是TS 传递过来的对象 (用于调用方法的对象);同时这个地方就不用传递参数数据映射了,也就是第4个参数就是传递 nullptr;

注意:size_t argc = 5;napi_value argv3 = {nullptr}; // 只有 3 个元素;在设置第2,3个参数时;数量不能设置不匹配否则就会出现越界;

napi_typeof(env, args0, &valuetype0);

参数含义
参数 方向 类型 说明
env in napi_env 当前 NAPI 执行环境上下文
value in napi_value 要获取类型的 JavaScript 值
result out napi_valuetype* 输出参数,用于接收类型枚举值
返回值

返回 napi_status 枚举值,表示操作结果:

返回值 说明
napi_ok 成功获取类型
napi_invalid_arg 参数无效(如 envvalueresultnullptr
napi_valuetype 枚举值
类型枚举 对应 ArkTS 类型
napi_undefined undefined
napi_null null
napi_boolean boolean
napi_number number
napi_string string
napi_symbol symbol
napi_object object
napi_function function
napi_external 外部数据
napi_bigint bigint
arduino 复制代码
   // 校验参数是否为函数
    if (type != napi_function) {
        napi_throw_type_error(env, nullptr, "Argument must be a function");
        return nullptr;
    }

napi_status napi_get_value_string_utf8

napi_status napi_get_value_string_utf8(napi_env env, napi_value value, char* buf, size_t bufsize, size_t* result);

参数含义
参数 方向 类型 说明
env in napi_env 当前 NAPI 执行环境上下文
value in napi_value 要获取的 JavaScript 字符串值(必须是 string 类型
buf in char* 用于存储字符串的缓冲区指针
bufsize in size_t 缓冲区大小(字节)
result out size_t* 输出参数,返回实际写入/复制的字节数(不含 null 终止符
返回值
返回值 说明
napi_ok 成功获取字符串
napi_string_expected value 不是字符串类型
napi_invalid_arg 参数无效
获取字符串长度
ini 复制代码
// 传入 buf = nullptr, bufsize = 0
// result 将返回字符串的字节长度(不含 null 终止符)
size_t strLen = 0;
napi_status status = napi_get_value_string_utf8(env, args[0], nullptr, 0, &strLen);
获取字符串内容
scss 复制代码
// 传入有效的缓冲区
char* buf = new char[strLen + 1];  // +1 用于存储 null 终止符
napi_get_value_string_utf8(env, args[0], buf, strLen + 1, &strLen);
// buf 现在包含字符串内容
动态分配内存获取字符串
ini 复制代码
#include "napi/native_api.h"
#include <cstring>

static napi_value GetStringDemo(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);

    // 1. 校验参数是否为字符串类型
    napi_valuetype type;
    napi_typeof(env, args[0], &type);
    if (type != napi_string) {
        napi_throw_type_error(env, nullptr, "Argument must be a string");
        return nullptr;
    }

    // 2. 获取字符串长度
    size_t strLen = 0;
    napi_status status = napi_get_value_string_utf8(env, args[0], nullptr, 0, &strLen);
    if (status != napi_ok) {
        return nullptr;
    }
    // 3. 分配缓冲区(+1 用于 null 终止符)
    char* buf = new char[strLen + 1];
    // 4. 获取字符串内容
    size_t copiedLen = 0;
    status = napi_get_value_string_utf8(env, args[0], buf, strLen + 1, &copiedLen);

    if (status == napi_ok) {
        // 使用字符串
        // buf[strLen] = '\0';  // 已经自动添加了 null 终止符
    }

    // 5. 释放内存
    delete[] buf;

    return nullptr;
}
示例二:使用固定大小缓冲区
ini 复制代码
static napi_value GetFixedString(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);

    // 使用固定大小的缓冲区
    char buf[256];
    size_t copiedLen = 0;

    napi_status status = napi_get_value_string_utf8(env, args[0], buf, sizeof(buf), &copiedLen);

    if (status == napi_ok) {
        // 如果字符串长度超过 255,会被截断
        // copiedLen 返回实际复制的字节数
    }

    return nullptr;
}
示例三:转换为 std::string
arduino 复制代码
#include <string>

static napi_value ConvertToStdString(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);

    // 获取长度
    size_t strLen = 0;
    napi_get_value_string_utf8(env, args[0], nullptr, 0, &strLen);

    // 分配并获取内容
    char* buf = new char[strLen + 1];
    napi_get_value_string_utf8(env, args[0], buf, strLen + 1, &strLen);

    // 转换为 std::string
    std::string cppStr(buf);

    delete[] buf;

    // 使用 cppStr...

    return nullptr;
}
重要注意事项
注意点 说明
null 终止符 函数会自动在字符串末尾添加 \0,缓冲区大小需要 strLen + 1
字节长度 strLen 返回的是字节长度,不是字符数(UTF-8 中多字节字符占多个字节
截断行为 如果 bufsize 小于字符串长度,字符串会被截断
类型检查 调用前应确保 value 是字符串类型,否则返回 napi_string_expected
内存管理 动态分配的缓冲区需要手动释放,避免内存泄漏

napi_get_value_double 参数详解

napi_status napi_get_value_double(napi_env env, napi_value value, double* result);

参数含义
参数 方向 类型 说明
env in napi_env 当前 NAPI 执行环境上下文
value in napi_value 要获取的 JavaScript 数值(必须是 number 类型
result out double* 输出参数,用于存储获取到的 double 值
返回值
返回值 说明
napi_ok 成功获取数值
napi_number_expected value 不是数字类型
napi_invalid_arg 参数无效(如 resultnullptr

基础用法:

arduino 复制代码
#include "napi/native_api.h"

static napi_value GetDoubleDemo(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);

    // 获取 double 值
    double value = 0.0;
    napi_status status = napi_get_value_double(env, args[0], &value);

    if (status != napi_ok) {
        // 处理错误
        return nullptr;
    }

    // 使用 value...

    return nullptr;
}
相关函数对比
函数 C++ 类型 JavaScript 类型 说明
napi_get_value_double double number 获取双精度浮点数
napi_get_value_int32 int32_t number 获取 32 位整数(会截断小数)
napi_get_value_uint32 uint32_t number 获取无符号 32 位整数
napi_get_value_int64 int64_t number 获取 64 位整数
napi_get_value_bigint_int64 int64_t bigint 从 BigInt 获取 64 位整数
napi_get_value_bigint_uint64 uint64_t bigint 从 BigInt 获取无符号 64 位整数
注意事项
注意点 说明
精度 JavaScript 的 number 类型是 IEEE 754 双精度浮点数,与 C++ double 一一对应
类型检查 如果传入非数字类型,返回 napi_number_expected
整数截断 如需整数,建议使用 napi_get_value_int32napi_get_value_int64
NaN 和 Infinity 可以正确获取 NaNInfinity-Infinity 等特殊值

napi_create_string_utf8 参数详解

napi_status napi_create_string_utf8(napi_env env, const char* str, size_t length, napi_value* result);

参数含义
参数 方向 类型 说明
env in napi_env 当前 NAPI 执行环境上下文
str in const char* C 风格字符串指针(UTF-8 编码)
length in size_t 字符串的字节长度(不含 null 终止符)
result out napi_value* 输出参数,用于存储创建的 JavaScript 字符串
返回值
返回值 说明
napi_ok 成功创建字符串
napi_invalid_arg 参数无效(如 strresultnullptr
从 C 字符串创建
arduino 复制代码
#include "napi/native_api.h"

static napi_value CreateStringDemo(napi_env env, napi_callback_info info) {
    const char* cStr = "Hello, HarmonyOS!";

    // 创建 JavaScript 字符串
    napi_value result;
    napi_status status = napi_create_string_utf8(env, cStr, strlen(cStr), &result);

    if (status != napi_ok) {
        return nullptr;
    }

    return result;
}
从 std::string 创建
c 复制代码
#include <string>

static napi_value CreateFromString(napi_env env, napi_callback_info info) {
    std::string cppStr = "Hello from C++";

    napi_value result;
    napi_status status = napi_create_string_utf8(
        env, 
        cppStr.c_str(),   // 转换为 const char*
        cppStr.length(),  // 字节长度
        &result
    );

    if (status != napi_ok) {
        return nullptr;
    }

    return result;
}
使用 NAPI_AUTO_LENGTH
ini 复制代码
static napi_value CreateWithAutoLength(napi_env env, napi_callback_info info) {
    const char* str = "Hello";

    napi_value result;
    // NAPI_AUTO_LENGTH 表示字符串以 null 结尾,自动计算长度
    napi_status status = napi_create_string_utf8(
        env, 
        str, 
        NAPI_AUTO_LENGTH,  // 自动计算长度
        &result
    );

    return result;
}
Length 参数详解
方式 说明
strlen(str) 手动计算字节长度
NAPI_AUTO_LENGTH 自动计算(字符串必须以 \0 结尾)
cppStr.length() std::string 获取长度
相关函数对比
函数 编码 说明
napi_create_string_utf8 UTF-8 创建 UTF-8 编码字符串
napi_create_string_latin1 Latin-1 创建 Latin-1 编码字符串(仅支持单字节字符)
napi_create_string_utf16 UTF-16 创建 UTF-16 编码字符串
注意事项
注意点 说明
字节长度 length字节长度,不是字符数(UTF-8 中文字符占 3 字节)
null 终止符 length 不包含 \0 终止符
编码要求 字符串必须是有效的 UTF-8 编码
内存管理 创建后 JavaScript 引擎会复制字符串,原字符串可立即释放
NAPI_AUTO_LENGTH 使用时确保字符串以 \0 结尾
napi_create_double 参数详解

napi_status napi_create_double(napi_env env, double value, napi_value* result);

参数含义
参数 方向 类型 说明
env in napi_env 当前 NAPI 执行环境上下文
value in double 要转换的 C++ 双精度浮点数
result out napi_value* 输出参数,用于存储创建的 JavaScript number
返回值
返回值 说明
napi_ok 成功创建数值
napi_invalid_arg 参数无效(如 resultnullptr
基本用法
arduino 复制代码
#include "napi/native_api.h"

static napi_value CreateDoubleDemo(napi_env env, napi_callback_info info) {
    double value = 3.14159;

    // 创建 JavaScript number
    napi_value result;
    napi_status status = napi_create_double(env, value, &result);

    if (status != napi_ok) {
        return nullptr;
    }

    return result;
}
相关创建函数对比
函数 C++ 类型 JavaScript 类型 说明
napi_create_double double number 创建双精度浮点数
napi_create_int32 int32_t number 创建 32 位整数
napi_create_uint32 uint32_t number 创建无符号 32 位整数
napi_create_int64 int64_t number 创建 64 位整数
napi_create_bigint_int64 int64_t bigint 创建 64 位 BigInt
napi_create_bigint_uint64 uint64_t bigint 创建无符号 64 位 BigInt
注意事项
注意点 说明
精度 JavaScript number 与 C++ double 精度一致(IEEE 754 双精度)
特殊值 可正确处理 NaNInfinity-Infinity
整数优化 如确定是整数,可用 napi_create_int32napi_create_int64
大整数 超过 53 位精度的整数应使用 BigInt 相关函数
napi_set_named_property 参数详解

napi_status napi_set_named_property(napi_env env, napi_value object, const char* utf8name, napi_value value);

目的:给参数里的 obj 对象,挂载指定名称的属性和值。(其实就是将需要数据封装成 obj 对象传递个 TS层)

参数含义
参数 方向 类型 说明
env in napi_env 当前 NAPI 执行环境上下文
object in napi_value 要设置属性的 JavaScript 对象
utf8name in const char* 属性名称(UTF-8 编码的 C 字符串)
value in napi_value 要设置的属性值
返回值
返回值 说明
napi_ok 成功设置属性
napi_invalid_arg 参数无效(如 object 不是对象)
创建对象并设置基本属性
scss 复制代码
#include "napi/native_api.h"

static napi_value CreateObjectDemo(napi_env env, napi_callback_info info) {
    // 1. 创建空对象
    napi_value obj;
    napi_create_object(env, &obj);

    // 2. 创建各种类型的值
    napi_value numVal;
    napi_value strVal;
    napi_value boolVal;

    napi_create_double(env, 3.14, &numVal);
    napi_create_string_utf8(env, "Hello", NAPI_AUTO_LENGTH, &strVal);
    napi_get_boolean(env, true, &boolVal);

    // 3. 设置属性
    napi_set_named_property(env, obj, "number", numVal);
    napi_set_named_property(env, obj, "string", strVal);
    napi_set_named_property(env, obj, "boolean", boolVal);

    return obj;
}
相关函数对比
函数 属性名类型 说明
napi_set_named_property const char* 使用 UTF-8 字符串作为属性名
napi_set_property napi_value 使用 napi_value 作为属性名(可以是任意类型)

napi_get_named_property 参数详解

napi_status napi_get_named_property(napi_env env, napi_value object, const char* utf8name, napi_value* result);

  • 使用场景

    C++ Native 层拿到 TS/JS 传过来的对象,按字段名提取数据

  • 读写配对

    • 存属性:napi_set_named_property(C++ 给对象加字段)
    • 取属性:napi_get_named_property(C++ 从对象读字段)
参数含义
参数 方向 类型 说明
env in napi_env 当前 NAPI 执行环境上下文
object in napi_value 要获取属性的 JavaScript 对象
utf8name in const char* 属性名称(UTF-8 编码的 C 字符串)
result out napi_value* 输出参数,用于存储获取到的属性值
返回值
返回值 说明
napi_ok 成功获取属性
napi_invalid_arg 参数无效(如 object 不是对象、resultnullptr
基本用法
arduino 复制代码
#include "napi/native_api.h"

static napi_value GetPropertyDemo(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;
    napi_status status = napi_get_named_property(env, args[0], "myProperty", &value);

    if (status != napi_ok) {
        return nullptr;
    }

    return value;
}
获取并转换数值属性
ini 复制代码
static napi_value GetNumberProperty(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 propValue;
    napi_get_named_property(env, args[0], "count", &propValue);

    // 转换为 double
    double count = 0.0;
    napi_get_value_double(env, propValue, &count);

    // 返回处理后的值
    napi_value result;
    napi_create_double(env, count * 2, &result);

    return result;
}
获取多个属性
scss 复制代码
static napi_value GetMultipleProperties(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 xVal, yVal, zVal;
    napi_get_named_property(env, args[0], "x", &xVal);
    napi_get_named_property(env, args[0], "y", &yVal);
    napi_get_named_property(env, args[0], "z", &zVal);

    // 转换为 double
    double x = 0.0, y = 0.0, z = 0.0;
    napi_get_value_double(env, xVal, &x);
    napi_get_value_double(env, yVal, &y);
    napi_get_value_double(env, zVal, &z);

    // 计算结果
    double sum = x + y + z;

    // 返回结果
    napi_value result;
    napi_create_double(env, sum, &result);

    return result;
}
获取嵌套对象属性
ini 复制代码
static napi_value GetNestedProperty(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 inner;
    napi_get_named_property(env, args[0], "inner", &inner);

    // 获取嵌套对象中的属性
    napi_value value;
    napi_get_named_property(env, inner, "value", &value);

    return value;
}
检查属性是否存在
ini 复制代码
static napi_value GetPropertySafely(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 hasProperty = false;
    napi_value key;
    napi_create_string_utf8(env, "myProperty", NAPI_AUTO_LENGTH, &key);
    napi_has_property(env, args[0], key, &hasProperty);

    if (!hasProperty) {
        // 属性不存在,返回默认值
        napi_value defaultValue;
        napi_get_undefined(env, &defaultValue);
        return defaultValue;
    }

    // 获取属性值
    napi_value value;
    napi_get_named_property(env, args[0], "myProperty", &value);

    return value;
}
获取数组属性
ini 复制代码
static napi_value GetArrayProperty(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 arr;
    napi_get_named_property(env, args[0], "numbers", &arr);

    // 确认是数组
    bool isArray = false;
    napi_is_array(env, arr, &isArray);

    if (!isArray) {
        return nullptr;
    }

    // 获取数组长度
    uint32_t length = 0;
    napi_get_array_length(env, arr, &length);

    // 遍历数组计算总和
    double sum = 0.0;
    for (uint32_t i = 0; i < length; i++) {
        napi_value element;
        napi_get_element(env, arr, i, &element);

        double num = 0.0;
        napi_get_value_double(env, element, &num);
        sum += num;
    }

    // 返回总和
    napi_value result;
    napi_create_double(env, sum, &result);

    return result;
}
相关函数对比
函数 属性名类型 说明
napi_get_named_property const char* 使用 UTF-8 字符串作为属性名
napi_get_property napi_value 使用 napi_value 作为属性名
检查属性是否存在
函数 说明
napi_has_named_property 检查命名属性是否存在
napi_has_property 检查属性是否存在(使用 napi_value 作为键)
ini 复制代码
static napi_value CheckPropertyDemo(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 hasProp = false;
    napi_has_named_property(env, args[0], "myProperty", &hasProp);

    napi_value result;
    napi_get_boolean(env, hasProp, &result);

    return result;
}

napi_call_function 参数详解

napi_status napi_call_function(napi_env env, napi_value this_arg, napi_value func, size_t argc, const napi_value* argv, napi_value* result);

常用场景

  1. TS 把回调函数传给 Native,Native 做完任务后回调 TS(最常见);
  2. Native 主动加载 TS 模块,调用模块里的导出函数。
参数含义
参数 方向 类型 说明
env in napi_env 当前 NAPI 执行环境上下文
this_arg in napi_value 函数调用时的 this
func in napi_value 要调用的 JavaScript 函数
argc in size_t 参数个数
argv in const napi_value* 参数数组指针
result out napi_value* 输出参数,存储函数返回值
返回值
返回值 说明
napi_ok 成功调用函数
napi_function_expected func 不是函数类型
napi_invalid_arg 参数无效
this_arg 参数
场景 传入值 说明
普通函数调用 undefinednull 相当于 func.call(null, ...)
对象方法调用 对象本身 相当于 obj.method.call(obj, ...)
构造函数调用 不适用(使用 napi_new_instance 创建新实例
无参数调用
ini 复制代码
#include "napi/native_api.h"

static napi_value CallNoArgs(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);

    // args[0] 是回调函数
    napi_value undefined;
    napi_get_undefined(env, &undefined);

    // 调用无参数函数
    napi_value result;
    napi_status status = napi_call_function(env, undefined, args[0], 0, nullptr, &result);

    if (status != napi_ok) {
        return nullptr;
    }

    return result;
}
带参数调用
ini 复制代码
static napi_value CallWithArgs(napi_env env, napi_callback_info info) {
    size_t argc = 3;
    napi_value args[3] = {nullptr};
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    // args[0] 是回调函数
    // args[1], args[2] 是要传递的参数

    napi_value undefined;
    napi_get_undefined(env, &undefined);

    // 准备参数数组
    napi_value callArgs[2] = {args[1], args[2]};

    // 调用函数,传入 2 个参数
    napi_value result;
    napi_call_function(env, undefined, args[0], 2, callArgs, &result);

    return result;
}
调用并获取返回值
ini 复制代码
static napi_value CallAndProcessResult(napi_env env, napi_callback_info info) {
    size_t argc = 2;
    napi_value args[2] = {nullptr};
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    // args[0] 是回调函数
    // args[1] 是参数

    napi_value undefined;
    napi_get_undefined(env, &undefined);

    // 调用函数
    napi_value callArgs[1] = {args[1]};
    napi_value result;
    napi_status status = napi_call_function(env, undefined, args[0], 1, callArgs, &result);

    if (status != napi_ok) {
        // 调用失败
        return nullptr;
    }

    // 处理返回值
    napi_valuetype type;
    napi_typeof(env, result, &type);

    if (type == napi_number) {
        double num = 0.0;
        napi_get_value_double(env, result, &num);
        // 处理数字...
    }

    return result;
}
调用对象方法
scss 复制代码
static napi_value CallObjectMethod(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);

    // args[0] 是对象

    // 获取对象的方法
    napi_value method;
    napi_get_named_property(env, args[0], "myMethod", &method);

    // 检查是否为函数
    napi_valuetype type;
    napi_typeof(env, method, &type);

    if (type != napi_function) {
        napi_throw_type_error(env, nullptr, "myMethod is not a function");
        return nullptr;
    }

    // 调用方法,this 指向对象本身
    napi_value result;
    napi_call_function(env, args[0], method, 0, nullptr, &result);

    return result;
}
typescript 复制代码
export interface MyObject {
  myMethod(): void;
}

/**
 * 调用对象的 myMethod 方法
 * @param obj - 包含 myMethod 方法的对象
 */
export const callObjectMethod: (obj: MyObject) => void;


调用:
     Button('调用对象方法')
        .onClick(() => {
          // 定义包含 myMethod 的对象
          const myObj = {
            myMethod: () => {
              console.log('myMethod 被调用了!');
            }
          };

          // 调用 Native 方法
          callObjectMethod(myObj);
        });

napi_create_function 参数详解

arduino 复制代码
napi_status napi_create_function(
  napi_env env,          // NAPI 运行环境
  const char* utf8name, // 函数名称(调试/栈追踪用)
  size_t length,        // 函数名字符串长度,传 NAPI_AUTO_LENGTH 自动计算
  napi_callback cb,     // 【核心】C++ 回调函数,函数实际逻辑写在这里
  void* data,           // 自定义上下文数据,会透传给 cb 回调,无需求传 nullptr
  napi_value* result    // 输出:创建好的 JS 函数对象(napi_value)
);

****作用:****napi_create_function在 Native (C/C++) 里创建一个可被 JS/TS 调用的函数对象 ,用于把 C++ 逻辑暴露成 TS/JS 可直接调用的方法

参数含义
参数 方向 类型 说明
env in napi_env 当前 NAPI 执行环境上下文
utf8name in const char* 函数名称(UTF-8 编码),可为 nullptr
length in size_t 函数名称的字节长度,可使用 NAPI_AUTO_LENGTH
cb in napi_callback C++ 回调函数指针
data in void* 用户自定义数据,传递给回调函数
result out napi_value* 输出参数,存储创建的 JavaScript 函数
返回值
返回值 说明
napi_ok 成功创建函数
napi_invalid_arg 参数无效(如 cbresultnullptr
napi_callback 类型定义
arduino 复制代码
typedef napi_value (*napi_callback)(napi_env env, napi_callback_info info);

回调函数签名:

  • 参数 env:NAPI 环境上下文
  • 参数 info:回调信息,可通过 napi_get_cb_info 获取参数
  • 返回值:函数的返回值(napi_value
基本用法
arduino 复制代码
#include "napi/native_api.h"

// 回调函数实现
static napi_value MyCallback(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);

    // 处理并返回
    double value = 0.0;
    napi_get_value_double(env, args[0], &value);

    napi_value result;
    napi_create_double(env, value * 2, &result);

    return result;
}

// 创建函数
static napi_value CreateFunctionDemo(napi_env env, napi_callback_info info) {
    napi_value func;
    napi_status status = napi_create_function(
        env,                    // 环境上下文
        "doubleIt",             // 函数名
        NAPI_AUTO_LENGTH,       // 自动计算名称长度
        MyCallback,             // 回调函数
        nullptr,                // 用户数据
        &func                   // 输出:创建的函数
    );

    if (status != napi_ok) {
        return nullptr;
    }

    // 返回创建的函数
    return func;
}
使用用户数据
ini 复制代码
// 用户数据结构
typedef struct {
    double multiplier;
    const char* name;
} UserData;

// 回调函数
static napi_value MultiplyCallback(napi_env env, napi_callback_info info) {
    // 获取用户数据
    void* data = nullptr;
    napi_get_cb_info(env, info, nullptr, nullptr, nullptr, &data);

    UserData* userData = (UserData*)data;

    // 获取参数
    size_t argc = 1;
    napi_value args[1] = {nullptr};
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    double value = 0.0;
    napi_get_value_double(env, args[0], &value);

    // 使用用户数据进行计算
    double result = value * userData->multiplier;

    napi_value jsResult;
    napi_create_double(env, result, &jsResult);

    return jsResult;
}

// 创建带用户数据的函数
static napi_value CreateMultiplyFunction(napi_env env, napi_callback_info info) {
    // 准备用户数据
    static UserData data = { 3.0, "triple" };

    napi_value func;
    napi_create_function(
        env,
        "triple",
        NAPI_AUTO_LENGTH,
        MultiplyCallback,
        &data,          // 传递用户数据
        &func
    );

    return func;
}
匿名函数(无名称)
scss 复制代码
static napi_value SimpleCallback(napi_env env, napi_callback_info info) {
    napi_value result;
    napi_create_double(env, 42, &result);
    return result;
}

static napi_value CreateAnonymousFunction(napi_env env, napi_callback_info info) {
    napi_value func;
    napi_create_function(
        env,
        nullptr,            // 匿名函数,无名称
        0,
        SimpleCallback,
        nullptr,
        &func
    );

    return func;
}
创建并调用函数
scss 复制代码
static napi_value AddCallback(napi_env env, napi_callback_info info) {
    size_t argc = 2;
    napi_value args[2] = {nullptr};
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    double a = 0.0, b = 0.0;
    napi_get_value_double(env, args[0], &a);
    napi_get_value_double(env, args[1], &b);

    napi_value result;
    napi_create_double(env, a + b, &result);

    return result;
}

static napi_value CreateAndCall(napi_env env, napi_callback_info info) {
    // 1. 创建函数
    napi_value addFunc;
    napi_create_function(env, "add", NAPI_AUTO_LENGTH, AddCallback, nullptr, &addFunc);

    // 2. 准备参数
    napi_value a, b;
    napi_create_double(env, 10, &a);
    napi_create_double(env, 20, &b);

    napi_value args[2] = {a, b};

    // 3. 调用函数
    napi_value undefined;
    napi_get_undefined(env, &undefined);

    napi_value result;
    napi_call_function(env, undefined, addFunc, 2, args, &result);

    return result;  // 返回 30
}
将函数作为对象方法
scss 复制代码
static napi_value GetNameCallback(napi_env env, napi_callback_info info) {
    napi_value result;
    napi_create_string_utf8(env, "MyObject", NAPI_AUTO_LENGTH, &result);
    return result;
}

static napi_value GetValueCallback(napi_env env, napi_callback_info info) {
    napi_value result;
    napi_create_double(env, 100.0, &result);
    return result;
}

static napi_value CreateObjectWithMethods(napi_env env, napi_callback_info info) {
    // 创建对象
    napi_value obj;
    napi_create_object(env, &obj);

    // 创建方法函数
    napi_value getName, getValue;
    napi_create_function(env, "getName", NAPI_AUTO_LENGTH, GetNameCallback, nullptr, &getName);
    napi_create_function(env, "getValue", NAPI_AUTO_LENGTH, GetValueCallback, nullptr, &getValue);

    // 将函数设置为对象属性
    napi_set_named_property(env, obj, "getName", getName);
    napi_set_named_property(env, obj, "getValue", getValue);

    return obj;
}
函数工厂模式
ini 复制代码
// 通用的乘法回调
static napi_value MultiplierCallback(napi_env env, napi_callback_info info) {
    void* data = nullptr;
    napi_get_cb_info(env, info, nullptr, nullptr, nullptr, &data);

    double multiplier = *(double*)data;

    size_t argc = 1;
    napi_value args[1] = {nullptr};
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    double value = 0.0;
    napi_get_value_double(env, args[0], &value);

    napi_value result;
    napi_create_double(env, value * multiplier, &result);

    return result;
}

// 工厂函数:创建指定倍数的乘法函数
static napi_value CreateMultiplier(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);

    double multiplier = 0.0;
    napi_get_value_double(env, args[0], &multiplier);

    // 注意:需要管理 multiplier 的生命周期
    double* data = new double(multiplier);

    napi_value func;
    napi_create_function(
        env,
        "multiply",
        NAPI_AUTO_LENGTH,
        MultiplierCallback,
        data,
        &func
    );

    return func;
}

区别:在.d.ts 文件中创建方法调用和通过napi_create_function创建方法;

css 复制代码
────────────────────────────────────────────────────────────────────────┐
│                        静态导出(常用)                                │
├────────────────────────────────────────────────────────────────────────┤
│  C++: napi_define_properties() 导出固定方法                           │
│  TS:  直接调用 import { add } from 'libentry'                        │
│  场景: 模块的基础功能方法                                              │
│  是否需要 napi_create_function: ❌ 不需要                             │
└────────────────────────────────────────────────────────────────────────┘

┌────────────────────────────────────────────────────────────────────────┐
│                        动态创建函数(特殊场景)                        │
├────────────────────────────────────────────────────────────────────────┤
│  C++: napi_create_function() 运行时创建函数                           │
│  TS:  接收函数作为返回值,如 createMultiplier(2)                      │
│  场景: 函数工厂、高阶函数、动态方法                                    │
│  是否需要 napi_create_function: ✅ 需要       

napi_get_element

napi_status napi_get_element(napi_env env, napi_value object, uint32_t index, napi_value* result);

参数含义
参数 类型 方向 说明
env napi_env in 调用 API 的环境上下文
object napi_value in 要从中获取元素的 ArkTS 数组对象
index uint32_t in 要获取的元素的索引位置
result napi_value* out 获取到的元素值,通过此参数返回

返回 napi_status 枚举值,表示操作状态:

  • napi_ok:操作成功
  • napi_object_expected:当参数 object 不是 Object 或 Function 对象时返回
  • 其他错误码表示相应的错误情况
注意事项
  • 请求索引值应在数组的有效范围内
  • 如果索引超出数组长度,函数会返回 undefined
1. C++ 侧实现
arduino 复制代码
#include "napi/native_api.h"

// 使用 Node-API 接口进行 array 相关开发 napi_get_element
static napi_value NapiGetElement(napi_env env, napi_callback_info info)
{
    // 获取 ArkTS 侧传入的参数
    size_t argc = 2;
    napi_value args[2] = {nullptr};
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    // 获取请求元素的索引值
    uint32_t index;
    napi_get_value_uint32(env, args[1], &index);

    // 获取请求索引位置的元素值并存储在 result 中
    napi_value result;
    napi_get_element(env, args[0], index, &result);

    return result;
}
2. 接口声明 (index.d.ts)
typescript 复制代码
export const napiGetElement: <T>(arr: Array<T>, index: number) => number | string | Object | boolean | undefined;
3. ArkTS 侧调用示例
typescript 复制代码
import { hilog } from '@kit.PerformanceAnalysisKit';
import testNapi from 'libentry.so';

// 定义接口类型
interface MyObject {
    first: number;
    second: number;
}

// 创建测试数据
let obj: MyObject = {
    first: 1,
    second: 2
};

let arr = [10, 'hello', null, obj];

// 获取不同类型的元素
hilog.info(0x0000, 'testTag', 'arr[0]: %{public}d', 
    testNapi.napiGetElement<number | string | null | Object>(arr, 0));

hilog.info(0x0000, 'testTag', 'arr[1]: %{public}s', 
    testNapi.napiGetElement<number | string | null | Object>(arr, 1));

hilog.info(0x0000, 'testTag', 'arr[2]: %{public}s', 
    testNapi.napiGetElement<number | string | null | Object>(arr, 2));

hilog.info(0x0000, 'testTag', 'arr[3]: %{public}s', 
    testNapi.napiGetElement<number | string | null | Object>(arr, 3));

// 索引超出范围时返回 undefined
hilog.info(0x0000, 'testTag', 'arr[4]: %{public}s', 
    JSON.stringify(testNapi.napiGetElement(arr, 4)));
相关接口
接口 描述
napi_set_element 在数组指定索引处设置元素值
napi_has_element 判断数组指定索引处是否包含元素
napi_delete_element 删除数组指定索引处的元素
napi_get_array_length 获取数组长度

napi_set_element

napi_status napi_set_element(napi_env env, napi_value object, uint32_t index, napi_value value);

参数说明
参数 类型 说明
env napi_env Node-API 执行时的上下文环境
object napi_value 目标对象(数组或支持索引访问的对象)
index uint32_t 要设置的元素索引位置
value napi_value 要设置的值
返回值

返回 napi_status 枚举值,表示操作是否成功:

  • napi_ok:操作成功
  • napi_object_expected:当参数 object 不是 Object 或 Function 对象时返回
C++ 侧代码
arduino 复制代码
#include "napi/native_api.h"

static constexpr int INT_ARG_2 = 2; // 入参索引

// napi_set_element
static napi_value NapiSetElement(napi_env env, napi_callback_info info)
{
    // 获取ArkTS侧传入的参数
    size_t argc = 3;
    napi_value args[3] = {nullptr};
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    // 检查第一个参数是否为数组
    bool isArr = false;
    napi_is_array(env, args[0], &isArr);
    if (!isArr) {
        napi_throw_type_error(env, nullptr, "Argument should be an object of type array");
        return nullptr;
    }

    // 获取要设置的元素索引
    double index = 0;
    napi_get_value_double(env, args[1], &index);

    // 将传入的值设置到数组指定索引位置
    napi_set_element(env, args[0], static_cast<uint32_t>(index), args[INT_ARG_2]);

    return nullptr;
}
接口声明
typescript 复制代码
export const napiSetElement: <T>(arr: Array<T>, index: number, value: T) => void;
ArkTS 侧示例代码
typescript 复制代码
import { hilog } from '@kit.PerformanceAnalysisKit';
import testNapi from 'libentry.so';

// napi_set_element
try {
    let arr = [10, 20, 30];
    testNapi.napiSetElement<number | string>(arr, 1, 'newElement');
    testNapi.napiSetElement<number | string>(arr, 2, 50);
    hilog.info(0x0000, 'testTag', 'Test Node-API napi_set_element arr: %{public}s', arr.toString());

    // 设置对象类型的元素
    interface MyObject {
        first: number;
        second: number;
    }
    let obj: MyObject = {
        first: 1,
        second: 2
    };
    testNapi.napiSetElement<number | string | Object>(arr, 4, obj);
    let objAsString = JSON.stringify(arr[4]);
    hilog.info(0x0000, 'testTag', 'Test Node-API napi_set_element arr[4]: %{public}s', objAsString);
} catch (error) {
    hilog.error(0x0000, 'testTag', 'Test Node-API napi_set_element error: %{public}s', error.message);
}

napi_create_array

napi_create_array 是 Node-API 提供的接口,用于在 Native 层创建一个空的 ArkTS 数组对象。

napi_status napi_create_array(napi_env env, napi_value* result);

参数说明
参数 类型 说明
env napi_env Node-API 执行时的上下文环境
result napi_value* 出参,用于接收创建的数组对象
返回值

返回 napi_status 枚举值,表示操作是否成功:

  • napi_ok:操作成功
C++ 侧代码
arduino 复制代码
#include "napi/native_api.h"

static constexpr int INT_NUM_5 = 5; // 数组长度

// napi_create_array
static napi_value CreateArray(napi_env env, napi_callback_info info)
{
    // 创建一个空数组
    napi_value jsArray = nullptr;
    napi_create_array(env, &jsArray);

    // 将创建好的数组进行赋值
    for (int i = 0; i < INT_NUM_5; i++) {
        napi_value element;
        napi_create_int32(env, i, &element);
        napi_set_element(env, jsArray, i, element);
    }

    // 返回已创建好的数组
    return jsArray;
}
接口声明
typescript 复制代码
export const createArray: () => number[];
ArkTS 侧示例代码
javascript 复制代码
import { hilog } from '@kit.PerformanceAnalysisKit';
import testNapi from 'libentry.so';

// napi_create_array
hilog.info(0x0000, 'testTag', 'Test Node-API napi_create_array:%{public}s', 
    JSON.stringify(testNapi.createArray()));
相关接口
接口 功能说明
napi_create_array 创建一个空的 ArkTS Array
napi_create_array_with_length 创建一个指定长度的 ArkTS Array
napi_get_array_length 获取 array 的 length
napi_is_array 判断给定 napi_value 是否为 array
napi_set_element 在数组指定索引处设置元素
napi_get_element 获取数组指定索引处的元素
创建指定长度数组

如果需要创建指定长度的数组,可以使用 napi_create_array_with_length

arduino 复制代码
#include "napi/native_api.h"

// napi_create_array_with_length
static napi_value CreateArrayWithLength(napi_env env, napi_callback_info info)
{
    // 获取ArkTS侧传入的参数
    size_t argc = 1;
    napi_value argv[1] = {nullptr};
    napi_value jsArray = nullptr;
    napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);

    // 获取传递的数组长度
    int32_t length = 0;
    napi_get_value_int32(env, argv[0], &length);

    // 使用napi_create_array_with_length创建指定长度的数组
    napi_create_array_with_length(env, length, &jsArray);

    // 返回数组
    return jsArray;
}
分类 常用函数
类型判断 napi_typeof, napi_is_array, napi_is_typedarray
创建值 napi_create_double, napi_create_string_utf8, napi_create_object, napi_create_array
获取值 napi_get_value_double, napi_get_value_string_utf8, napi_get_value_bool
特殊值 napi_get_undefined, napi_get_null, napi_get_boolean
对象 napi_get_named_property, napi_set_named_property
数组 napi_get_element, napi_set_element, napi_get_array_length
函数 napi_create_function, napi_call_function, napi_get_cb_info
错误 napi_throw_error, napi_throw_type_error
Promise napi_create_promise, napi_resolve_promise, napi_reject_promise
引用 napi_create_reference, napi_delete_reference
相关推荐
yuegu7771 小时前
HarmonyOS应用<节气通>开发第24篇:响应式布局设计
深度学习·harmonyos
JohnnyDeng942 小时前
【鸿蒙】HarmonyOS 通知与后台任务:WorkScheduler 机制深度解析
harmonyos·arkts·鸿蒙·arkui·后台任务
祭曦念2 小时前
BLOG_番茄钟开发实战
华为·harmonyos
TrisighT2 小时前
Electron 本地图片在鸿蒙 PC 上白图,我注册了个自定义协议
electron·harmonyos
祭曦念2 小时前
鸿蒙原生 ArkTS 布局探索(一):FlexRowReverse 弹性布局深度解析
华为·harmonyos
Swift社区3 小时前
鸿蒙游戏如何实现稳定 60FPS?
游戏·华为·harmonyos
风华圆舞3 小时前
MethodChannel 在 Flutter 与 ArkTS 之间是怎么工作的
flutter·华为·harmonyos
G_dou_3 小时前
Flutter三方库适配OpenHarmony【prime_checker】质数检测器项目完整实战
flutter·harmonyos
G_dou_3 小时前
Flutter三方库适配OpenHarmony【random_joke】随机笑话应用项目完整实战
flutter·harmonyos