鸿蒙 NDK开发:Node-API 开发class相关(八)

一、类、实例、原型

概念说明
类(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实例
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值