内容可能存在错误,也可能由于版本更新存在差异;请各位大佬自行甄别;
napi_status napi_get_cb_info
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 用于判断结果是否正确;判断逻辑如下:
if (status != napi_ok || argc < 1)// argc 是对应的参数个数;设置了一个参数判断几个
{
return "";//根据条件进行返回
}
动态的获取参数数据:
#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 对象模式:
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 |
参数无效(如 env、value 或 result 为 nullptr) |
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 |
// 校验参数是否为函数
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 |
参数无效 |
获取字符串长度
// 传入 buf = nullptr, bufsize = 0
// result 将返回字符串的字节长度(不含 null 终止符)
size_t strLen = 0;
napi_status status = napi_get_value_string_utf8(env, args[0], nullptr, 0, &strLen);
获取字符串内容
// 传入有效的缓冲区
char* buf = new char[strLen + 1]; // +1 用于存储 null 终止符
napi_get_value_string_utf8(env, args[0], buf, strLen + 1, &strLen);
// buf 现在包含字符串内容
动态分配内存获取字符串
#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;
}
示例二:使用固定大小缓冲区
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
#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 |
参数无效(如 result 为 nullptr) |
基础用法:
#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_int32 或 napi_get_value_int64 |
| NaN 和 Infinity |
可以正确获取 NaN、Infinity、-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 |
参数无效(如 str 或 result 为 nullptr) |
从 C 字符串创建
#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 创建
#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
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 |
参数无效(如 result 为 nullptr) |
基本用法
#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 双精度) |
| 特殊值 |
可正确处理 NaN、Infinity、-Infinity |
| 整数优化 |
如确定是整数,可用 napi_create_int32 或 napi_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 不是对象) |
创建对象并设置基本属性
#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);
参数含义
| 参数 |
方向 |
类型 |
说明 |
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 不是对象、result 为 nullptr) |
基本用法
#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;
}
获取并转换数值属性
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;
}
获取多个属性
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;
}
获取嵌套对象属性
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;
}
检查属性是否存在
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;
}
获取数组属性
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 作为键) |
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);
常用场景:
- TS 把回调函数传给 Native,Native 做完任务后回调 TS(最常见);
- 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 参数
| 场景 |
传入值 |
说明 |
| 普通函数调用 |
undefined 或 null |
相当于 func.call(null, ...) |
| 对象方法调用 |
对象本身 |
相当于 obj.method.call(obj, ...) |
| 构造函数调用 |
不适用(使用 napi_new_instance) |
创建新实例 |
无参数调用
#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;
}
带参数调用
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;
}
调用并获取返回值
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;
}
调用对象方法
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;
}
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 参数详解
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 |
参数无效(如 cb 或 result 为 nullptr) |
napi_callback 类型定义
typedef napi_value (*napi_callback)(napi_env env, napi_callback_info info);
回调函数签名:
- 参数
env:NAPI 环境上下文
- 参数
info:回调信息,可通过 napi_get_cb_info 获取参数
- 返回值:函数的返回值(
napi_value)
基本用法
#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;
}
使用用户数据
// 用户数据结构
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;
}
匿名函数(无名称)
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;
}
创建并调用函数
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
}
将函数作为对象方法
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;
}
函数工厂模式
// 通用的乘法回调
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创建方法;
────────────────────────────────────────────────────────────────────────┐
│ 静态导出(常用) │
├────────────────────────────────────────────────────────────────────────┤
│ 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++ 侧实现
#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)
export const napiGetElement: <T>(arr: Array<T>, index: number) => number | string | Object | boolean | undefined;
3. ArkTS 侧调用示例
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++ 侧代码
#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;
}
接口声明
export const napiSetElement: <T>(arr: Array<T>, index: number, value: T) => void;
ArkTS 侧示例代码
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 枚举值,表示操作是否成功:
C++ 侧代码
#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;
}
接口声明
export const createArray: () => number[];
ArkTS 侧示例代码
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:
#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 |