一、类、实例、原型
| 概念 | 说明 |
|---|---|
| 类(Class) | 用于创建对象的模板,封装数据和行为。在ArkTS中建立在原型(prototype)基础上 |
| 实例(Instance) | 通过类创建的具体对象,每个实例具有自己的属性值 |
| 原型(Prototype) | 对象通过原型链实现继承,参考EcmaScript规范 |
二、核心接口
| 接口 | 描述 |
|---|---|
napi_new_instance | 通过给定的构造函数构建一个实例 |
napi_get_new_target | 获取构造函数调用的new.target |
napi_define_class | 在Node-API模块定义与ArkTS类相对应的类 |
napi_wrap | 在ArkTS对象上绑定一个Node-API模块对象实例 |
napi_unwrap | 从ArkTS对象上获取之前绑定的Node-API模块对象实例 |
napi_remove_wrap | 从ArkTS对象上获取之前绑定的Node-API模块对象实例,并解除绑定 |
三、使用示例
3.1 napi_new_instance
通过给定的构造函数实例化一个对象,返回ArkTS端使用。
说明:参数constructor不是function类型则返回napi_function_expected。
cpp部分代码:
// napi_new_instance
static napi_value NewInstance(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);
// 实例化对象
napi_value result = nullptr;
napi_new_instance(env, args[0], 1, &args[1], &result);
return result;
}
接口声明(index.d.ts):
export const newInstance: (obj: Object, param: string) => Object;
ArkTS端示例:
class Fruit {
name: string;
constructor(name: string) {
this.name = name;
}
}
let obj = testNapi.newInstance(Fruit, 'test');
hilog.info(0x0000, 'Node-API', 'napi_new_instance %{public}s', JSON.stringify(obj));
3.2 napi_wrap / napi_unwrap / napi_remove_wrap
数据结构定义与析构回调
struct Object {
std::string name;
int32_t age;
};
static void DerefItem(napi_env env, void *data, void *hint) {
// 在ArkTS对象被垃圾回收时释放原生实例
Object *obj = reinterpret_cast<Object *>(data);
if (obj != nullptr) {
delete obj;
}
}
napi_wrap
在ArkTS object上绑定一个native对象实例。
说明:参数js_object不为object类型或function类型时返回napi_object_expected。
static napi_value Wrap(napi_env env, napi_callback_info info) {
struct Object *obj = new struct Object();
obj->name = "liLei";
obj->age = 18;
size_t argc = 1;
napi_value toWrap;
napi_get_cb_info(env, info, &argc, &toWrap, NULL, NULL);
napi_status status = napi_wrap(env, toWrap, reinterpret_cast<void *>(obj), DerefItem, NULL, NULL);
if (status != napi_ok) {
delete obj; // 失败时主动释放内存
}
return toWrap;
}
napi_remove_wrap
从ArkTS object上获取先前绑定的native对象实例,并解除绑定。
static napi_value RemoveWrap(napi_env env, napi_callback_info info) {
size_t argc = 1;
napi_value wrapped = nullptr;
void *data = nullptr;
napi_get_cb_info(env, info, &argc, &wrapped, nullptr, nullptr);
napi_status status = napi_remove_wrap(env, wrapped, &data);
if (status != napi_ok || data == nullptr) {
OH_LOG_ERROR(LOG_APP, "napi_remove_wrap failed or data is nullptr");
return nullptr;
}
return nullptr;
}
napi_unwrap
从一个被包装的对象中获取与之关联的数据指针。
static napi_value UnWrap(napi_env env, napi_callback_info info) {
size_t argc = 1;
napi_value wrapped = nullptr;
napi_get_cb_info(env, info, &argc, &wrapped, nullptr, nullptr);
struct Object *data = nullptr;
napi_status status = napi_unwrap(env, wrapped, reinterpret_cast<void ***>(&data));
if (status != napi_ok || data == nullptr) {
OH_LOG_ERROR(LOG_APP, "napi_unwrap failed or data is nullptr");
return nullptr;
}
OH_LOG_INFO(LOG_APP, "name: %{public}s", data->name.c_str());
OH_LOG_INFO(LOG_APP, "age: %{public}d", data->age);
return nullptr;
}
接口声明(index.d.ts)
export const wrap: (obj: Object) => Object; // napi_wrap
export const unWrap: (obj: Object) => void; // napi_unwrap
export const removeWrap: (obj: Object) => void; // napi_remove_wrap
ArkTS端示例
try {
class Obj {}
let obj: Obj = {};
testNapi.wrap(obj); // napi_wrap
testNapi.unWrap(obj); // napi_unwrap
testNapi.removeWrap(obj); // napi_remove_wrap
} catch (error) {
hilog.error(0x0000, 'testTag', 'Test Node-API error: %{public}s', error.message);
}
四、CMakeLists.txt配置
如需在Native C++中打印日志,需添加以下配置:
add_definitions( "-DLOG_DOMAIN=0xd0d0" )
add_definitions( "-DLOG_TAG=\"testTag\"" )
target_link_libraries(entry PUBLIC libace_napi.z.so libhilog_ndk.z.so)
并添加头文件:#include "hilog/log.h"
注意事项
| 注意事项 | 说明 |
|---|---|
| 类型检查 | napi_wrap/napi_unwrap/napi_remove_wrap的js_object参数不为object或function类型时返回napi_object_expected |
| 内存管理 | napi_wrap失败时需要主动释放Native内存;成功时由DerefItem在GC时释放 |
| 构造函数类型 | napi_new_instance的constructor参数不是function类型时返回napi_function_expected |
| GC回调 | DerefItem在ArkTS对象被垃圾回收时触发,用于释放Native实例 |

1175

被折叠的 条评论
为什么被折叠?



