ArkTS侧如何批量传递函数到native侧
======================

#### 问题现象

在native侧需要调用一系列ArkTS侧函数，如果每个方法都通过单独的参数传递到native侧的话，会比较繁琐，ArkTS侧如何批量传递函数到native侧？

#### 背景知识

*   [napi\_get\_element](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/use-napi-about-array#napi_get_element)：用于从ArkTS数组中获取请求索引位置的元素值。请求索引值应在数组的有效范围内，如果索引超出数组长度，函数会返回undefined。
*   [napi\_get\_named\_property](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/use-napi-about-property#napi_get_named_property)：用于从ArkTS对象中获取命名属性的值。

#### 解决方案

可以将函数包装在一个对象或者数组中，通过传递对象或数组达成传递一系列函数的目的。本文通过在数组中传递两个匿名函数及一个对象的方式完成ArkTS侧批量传递函数到native侧的目的。示例代码如下：

*   cpp文件：将数组传入到c++侧后，通过napi\_get\_element方法分别获得数组中的两个匿名函数及DataModel对象。在通过napi\_get\_named\_property方法获取DataModel对象中的方法，最后通过napi\_call\_function方法分别调用获得的方法。
    
    _/\*_
     _\* Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved._
     _\*/_
    #include "napi/native\_api.h"
    static napi\_value Test(napi\_env env, napi\_callback\_info info)
    {
       _ // 期望从ArkTS侧获取的参数的数量，napi\_value可理解为ArkTS value在native方法中的表现形式。_
        size\_t argc = 1;
        napi\_value args\[1\] = {nullptr};
    
       _ // 从info中，拿到从ArkTS侧传递过来的参数，此处获取了一个ArkTS参数，即arg\[0\]。_
        napi\_get\_cb\_info(env, info, &argc, args, nullptr, nullptr);
        _// 从arg\[0\]中获取ts侧传递的方法。_
        napi\_value mul = nullptr;
        napi\_get\_element(env, args\[0\], 0, &mul);
    
        napi\_value div = nullptr;
        napi\_get\_element(env, args\[0\], 1, &div);
    
       _ // 从arg\[0\]中获取ts侧传递的对象。_
        napi\_value DataModel = nullptr;
        napi\_get\_element(env, args\[0\], 2, &DataModel);
    
      _  // 获取对象中的方法。_
        napi\_value add, sub;
        napi\_get\_named\_property(env, DataModel, "add", &add);
        napi\_get\_named\_property(env, DataModel, "sub", &sub);
    
       _ // 创建参数数组。_
        napi\_value arr\[2\];
        napi\_create\_int32(env, 10, &arr\[0\]);
        napi\_create\_int32(env, 5, &arr\[1\]);
    
       _ // 创建一个ArkTS number作为ArkTS function的入参。_
        napi\_value argv = nullptr;
        napi\_create\_int32(env, 2, &argv);
    
        _// 创建一个初始长度为length的数组result。_
        napi\_value result;
        if (napi\_ok != napi\_create\_array\_with\_length(env, 4, &result)) {
            return nullptr;
        }
    
       _ // napi\_call\_function函数可以传递多个参数，传递函数的入参个数、类型、返回值类型不一致都适用此方法。_
        napi\_value resultAdd;
      _  // 调用方法add。_
      _  // napi\_call\_function传递两个参数。_
        napi\_call\_function(env, nullptr, add, 2, arr, &resultAdd);
        napi\_set\_element(env, result, 1, resultAdd);
       _ // 调用方法sub_
        napi\_value resultSub;
        napi\_call\_function(env, nullptr, sub, 2, arr, &resultSub);
        napi\_set\_element(env, result, 2, resultSub);
    
      _  // 调用方法mul。_
        _// napi\_call\_function传递一个参数。_
        napi\_value resultMul;
        napi\_call\_function(env, nullptr, mul, 1, &argv, &resultMul);
        napi\_set\_element(env, result, 3, resultMul);
    
        _// 调用方法div。_
        napi\_value resultDiv;
        napi\_call\_function(env, nullptr, div, 1, &argv, &resultDiv);
        napi\_set\_element(env, result, 4, resultDiv);
    
        return result;
    }
    
    EXTERN\_C\_START
    static napi\_value Init(napi\_env env, napi\_value exports)
    {
        napi\_property\_descriptor desc\[\] = {
            {"test", nullptr, Test, nullptr, nullptr, nullptr, napi\_default, nullptr}
        };
        napi\_define\_properties(env, exports, sizeof(desc) / sizeof(desc\[0\]), desc);
        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.ets：文件中创建一个arr数组，存放两个匿名函数及一个DataModel对象（DataModel中存在两个方法）。
    
    import { hilog } from '@kit.PerformanceAnalysisKit';
    import testNapi from 'libentry.so';
    import dataModel from '../pages/DataModel';
    
    let value: number = 10;
    
    @Entry
    @Component
    struct Index {
      build() {
        Row() {
          Column() {
            Text('test')
              .fontSize($r('app.float.page\_text\_font\_size'))
              .fontWeight(FontWeight.Bold)
              .onClick(() => {
                let arr: Object\[\] = \[\];
                arr\[0\] = () => {
                  return value \* 2;
                };
                arr\[1\] = () => {
                  return value / 2;
                };
                arr\[2\] = dataModel;
                let ret = testNapi.test(arr);
                hilog.info(0x0000, 'testTag', 'Test NAPI test ret = %{public}d', ret\[1\]);
                hilog.info(0x0000, 'testTag', 'Test NAPI test ret = %{public}d', ret\[2\]);
                hilog.info(0x0000, 'testTag', 'Test NAPI test ret = %{public}d', ret\[3\]);
                hilog.info(0x0000, 'testTag', 'Test NAPI test ret = %{public}d', ret\[4\]);
    
              });
          }
          .width('100%');
        }
        .height('100%');
      }
    }
    
*   DataModel.ets：导出DataModel类。
    
    class DataModel {
      add(a: number, b: number): number {
        return a + b;
      }
    
      sub(a: number, b: number): number {
        return a - b;
      }
    }
    
    export default new DataModel();