跳到主要内容

使用扩展的Node-API接口创建对ArkTS对象的强引用

HarmonyOS提供的API优化了强引用的创建效率,保留了Node-API的强引用特性,相较于napi_ref,napi_strong_ref具有更快的创建效率。

场景介绍

开发者可以通过napi_create_strong_reference接口创建指向ArkTS对象的强引用,并通过napi_get_strong_reference_value获取引用的ArkTS对象。

强引用对象关联接口

接口描述
napi_create_strong_reference创建指向ArkTS对象的强引用
napi_delete_strong_reference删除强引用
napi_get_strong_reference_value根据强引用对象获取其关联的ArkTS对象值

示例代码

  • 模块注册

    // napi_init.cpp
    #include "napi/native_api.h"
    #include <vector>

    // napi_strong_ref 不支持跨线程使用。示例为单线程场景。请勿在业务代码中使用此方式声明。
    static napi_strong_ref g_strongRef {};
    static napi_value NAPI_Global_saveOrReplaceObject(napi_env env, napi_callback_info info)
    {
    napi_value args[1]{};
    size_t argc = 1;
    napi_get_cb_info(env, info, &argc, args, /* thisVar */ nullptr, /* data */ nullptr);
    if (argc < 1) {
    return nullptr;
    }

    if (g_strongRef != nullptr) {
    napi_delete_strong_reference(env, g_strongRef);
    g_strongRef = nullptr;
    }
    napi_create_strong_reference(env, args[0], &g_strongRef);
    return nullptr;
    }

    static napi_value NAPI_Global_releaseObject(napi_env env, [[maybe_unused]] napi_callback_info info)
    {
    if (g_strongRef != nullptr) {
    napi_delete_strong_reference(env, g_strongRef);
    g_strongRef = nullptr;
    }
    return nullptr;
    }

    static napi_value NAPI_Global_queryObject(napi_env env, [[maybe_unused]] napi_callback_info info)
    {
    napi_value result {};
    napi_get_strong_reference_value(env, g_strongRef, &result);
    return result;
    }

    // 模块注册
    EXTERN_C_START
    static napi_value Init(napi_env env, napi_value exports)
    {
    std::vector<napi_property_descriptor> desc{
    {"saveOrReplaceObject", nullptr, NAPI_Global_saveOrReplaceObject, nullptr, nullptr, nullptr, napi_default, nullptr},
    {"releaseObject", nullptr, NAPI_Global_releaseObject, nullptr, nullptr, nullptr, napi_default, nullptr},
    {"queryObject", nullptr, NAPI_Global_queryObject, nullptr, nullptr, nullptr, napi_default, nullptr},
    };
    napi_define_properties(env, exports, desc.size(), desc.data());
    return exports;
    }
    EXTERN_C_END

    static napi_module demoModule = {
    .nm_version = 1,
    .nm_flags = 0,
    .nm_filename = nullptr,
    .nm_register_func = Init,
    .nm_modname = "entry",
    .nm_priv = ((void *)0),
    .reserved = {0},
    };

    extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
    {
    napi_module_register(&demoModule);
    }
  • 接口声明

    // index.d.ts
    export const saveOrReplaceObject: <T>(val: T) => void;
    export const queryObject: <T>() => T;
    export const releaseObject: () => void;
  • ArkTS代码示例

    // index.ets
    import testNapi from "libentry.so"

    const makeTest = <T>(val: T) => {
    testNapi.saveOrReplaceObject(val);
    const result = testNapi.queryObject<T>();
    testNapi.releaseObject();
    if (val !== result) {
    throw new Error("result not equals to input");
    }
    }

    // 预期以下调用无异常
    makeTest(0);
    makeTest("0");
    makeTest(true);
    makeTest(BigInt("0"));
    makeTest([]);
    makeTest(new Object());
    makeTest(undefined);
    makeTest(null);