使用扩展的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);