在进行鸿蒙开发的NDK 中,大家都知道如何进行用ArkTS 进行调取C的方法,
但是在实际的开发中,还会存在一个情况,就是C中如何调取ArkTS的方法,触发ArkTS里面的内容。
解决方案:
关键函数: napi_call_function
函数参数说明:
napi_status napi_call_function(
napi_env env, // 环境句柄
napi_value receiver, // 函数调用的 this 值,对于全局函数,通常传递 undefined(即 NULL)这个值在下一篇或者后面的文章中会用到,这个文章中传递null 就可以
napi_value func, // 要调用的 JavaScript 函数
size_t argc, // 参数数量
const napi_value* argv, // 参数数组
napi_value* result // 返回值(可选)
);
在C语言中的实现:
#include <node_api.h>

// 原生方法:接收一个 JS 函数并调用它
napi_value CallJSFunction(napi_env env, napi_callback_info info) {
napi_status status;
size_t argc = 0;
napi_value args[1];
napi_value result;

// 1. 获取参数数量
status = napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);
if (status != napi_ok) return nullptr;

// 2. 验证参数数量
if (argc < 1) {
napi_throw_type_error(env, nullptr, “需要一个参数”);
return nullptr;
}

// 3. 获取第一个参数
status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
if (status != napi_ok) return nullptr;

// 4. 验证参数是一个函数
bool isFunction;
status = napi_is_function(env, args[0], &isFunction);
if (status != napi_ok || !isFunction) {
napi_throw_type_error(env, nullptr, “参数必须是函数”);
return nullptr;
}

// 5. 创建传递给 JS 函数的参数
napi_value message;
status = napi_create_string_utf8(env, “Hello from C++”, NAPI_AUTO_LENGTH, &message);
if (status != napi_ok) return nullptr;

// 6. 准备参数数组
const napi_value argv[] = { message };

// 7. 调用 JavaScript 函数(this 值设为 null)
status = napi_call_function(env, nullptr, args[0], 1, argv, &result);
if (status != napi_ok) {
// 处理函数调用错误
napi_throw_error(env, nullptr, “调用 JavaScript 函数失败”);
return nullptr;
}

return result;
}

// 初始化模块
napi_value Init(napi_env env, napi_value exports) {
napi_status status;
napi_value fn;

// 创建原生方法
status = napi_create_function(env, nullptr, 0, CallJSFunction, nullptr, &fn);
if (status != napi_ok) return nullptr;

// 设置导出对象的属性
status = napi_set_named_property(env, exports, “callJSFunction”, fn);
if (status != napi_ok) return nullptr;

return exports;
}

// 定义模块入口
NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)

在JS 中调用
const addon = require(‘./build/Release/addon’);

// 定义要被调用的 JavaScript 函数
const callback = (message) => {
console.log(‘收到消息:’, message);
return ‘返回值 from JavaScript’;
};

// 调用原生方法,传递 JS 函数
const result = addon.callJSFunction(callback);
console.log(‘原生方法返回:’, result);

(中间还有一个NAPI)需要将C的接口暴露给TS层。
如果有不清晰的欢迎大家给提意见

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐