鸿蒙 NDK开发:函数创建与调用(十二)

   NDK开发中,函数操作是跨语言交互的核心能力。Node-API提供了3个关键接口用于获取函数调用信息、调用ArkTS函数和创建可在ArkTS中调用的函数。

一、函数

函数是一种非常重要的编程概念,可以执行特定的任务或操作、提高代码的可读性、把复杂任务简化、提高代码复用性以及支持代码的组织与管理。

二、核心接口

接口描述
napi_get_cb_info从给定的callback info中获取有关调用的参数信息和this指针
napi_call_function在Node-API模块中对ArkTS侧函数进行调用
napi_create_function将C/C++函数创建为可在ArkTS中调用的函数

三、使用示例

3.1 napi_get_cb_info

获取有关函数调用的详细信息,包括参数、参数个数和this指针。

cpp部分代码
#include "napi/native_api.h"

// 获取ArkTS侧入参的参数信息
static napi_value GetCbArgs(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value args[1] = {nullptr};
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    return args[0];
}

// 获取ArkTS侧入参的参数个数
static napi_value GetCbArgQuantity(napi_env env, napi_callback_info info) {
    size_t argc = 0;
    napi_value result = nullptr;
    napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);
    napi_create_int32(env, argc, &result);
    return result;
}

// 获取ArkTS侧this参数
static napi_value GetCbContext(napi_env env, napi_callback_info info) {
    napi_value thisArg = nullptr;
    napi_get_cb_info(env, info, nullptr, nullptr, &thisArg, nullptr);
    return thisArg;
}
接口声明(index.d.ts)
export const getCbArgs: <T>(arg: T) => T;  // napi_get_cb_info
export const getCbArgQuantity: (str: string, num: number) => number;
export const getCbContext: () => Object;
ArkTS侧示例
import { hilog } from '@kit.PerformanceAnalysisKit';
import testNapi from 'libentry.so';

function summation(arr: Array<number>) {
    let sum: number = 0;
    for (let i = 0; i < arr.length; i++) {
        sum += arr[i];
    }
    return sum;
}

const str = 'message';
const arr = [0, 1, 2, 3, 4, 5];
const num = 526;

class Student {
    name: string;
    age: number;
    score: number;
    constructor(name: string, age: number, score: number) {
        this.name = name;
        this.age = age;
        this.score = score;
    }
}

let student = new Student('Alice', 18, 100);

// 获取参数
hilog.info(0x0000, 'testTag', 'get string arg:%{public}s', testNapi.getCbArgs(str));
hilog.info(0x0000, 'testTag', 'get array arg:%{public}s', testNapi.getCbArgs(arr).toString());
hilog.info(0x0000, 'testTag', 'get num arg:%{public}d', testNapi.getCbArgs(num));
hilog.info(0x0000, 'testTag', 'get object arg:%{public}s', JSON.stringify(testNapi.getCbArgs(student)));
hilog.info(0x0000, 'testTag', 'get function arg:%{public}d', testNapi.getCbArgs(summation(arr)));

// 获取参数个数
hilog.info(0x0000, 'testTag', 'get arg quantity:%{public}d', testNapi.getCbArgQuantity(str, num));

// 获取上下文
hilog.info(0x0000, 'testTag', 'get thisArg:%{public}s', testNapi.getCbContext().toString());

3.2 napi_call_function

在C/C++侧对ArkTS函数进行调用。

注意事项napi_call_function传入的argv的长度必须大于等于argc声明的数量,并且每个元素都应初始化为nullptr。

cpp部分代码
// 在全局上下文中调用ArkTS函数
static napi_value CallFunction(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value argv[1] = {nullptr};
    napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
    
    // 获取全局对象作为this入参
    napi_value global = nullptr;
    napi_get_global(env, &global);
    
    napi_value result = nullptr;
    // argv长度必须>=argc数量,且每个元素都初始化为nullptr
    napi_call_function(env, global, argv[0], argc, argv, &result);
    return result;
}

// 在指定对象上下文中调用ArkTS函数
static napi_value ObjCallFunction(napi_env env, napi_callback_info info) {
    size_t argc = 2;
    napi_value argv[2] = {nullptr};
    napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
    
    napi_value result = nullptr;
    // 第一个参数是this对象,第二个参数是要调用的函数
    napi_call_function(env, argv[0], argv[1], argc, argv, &result);
    return result;
}
接口声明(index.d.ts)
export const callFunction: (func: Function) => number;       // napi_call_function
export const objCallFunction: (obj: Object, func: Function) => number;
ArkTS侧示例
function returnNumber() {
    return 10;
}

class Person {
    age(): number {
        return 11;
    }
}

const person = new Person();

hilog.info(0x0000, 'testTag', 'call_function:%{public}d', testNapi.callFunction(returnNumber));
hilog.info(0x0000, 'testTag', 'call_function:%{public}d', testNapi.objCallFunction(person, person.age));

3.3 napi_create_function

将一个C/C++函数包装为可在ArkTS中调用的函数,并返回一个表示该函数的napi_value。

cpp部分代码
// 计算矩形面积
static napi_value CalculateArea(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);
    
    double width = 0;
    napi_get_value_double(env, args[0], &width);
    double height = 0;
    napi_get_value_double(env, args[1], &height);
    
    napi_value area = nullptr;
    napi_create_double(env, width * height, &area);
    return area;
}
接口声明(index.d.ts)
export const calculateArea: (width: number, height: number) => number;  // napi_create_function
ArkTS侧示例
hilog.info(0x0000, 'testTag', 'create_function:%{public}d', testNapi.calculateArea(1.2, 4));

五、注意事项

注意事项说明
argv长度napi_call_function传入的argv长度必须>=argc数量
argv初始化每个元素都应初始化为nullptr
this指针napi_call_function需要传入this对象(通常为global或指定对象)
参数获取napi_get_cb_info中argv可传nullptr先获取参数数量
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值