赞
踩
ArkTS侧:实现C++方法的结果返回,以及实现其回调函数。
Native侧:.cpp文件,实现结果返回函数、回调函数以及设置回调数据。需要提供注册lib库的名称,并在注册回调方法中定义接口的映射关系,即Native方法及对应的ArkTS接口名称等。
ntry > src > main > cpp > types:用于存放C++的API接口描述文件。
entry > src > main > cpp > types > libentry > index.d.ts:描述C++ API接口行为,如接口名、入参、返回参数等。
entry > src > main > cpp > types > libentry > oh-package.json5:配置.so三方包声明文件的入口及包名。
entry > src > main > cpp > CMakeLists.txt:C++源码编译配置文件,提供CMake构建脚本。
entry > src > main > cpp > xxx.cpp:定义C++ API接口的文件。
ArkTS侧import native模块时,会加载其对应的so。加载so时,首先会调用napi_module_register方法,将模块注册到系统中,并调用模块初始化函数。
napi_module有两个关键属性:一个是.nm_register_func,定义模块初始化函数;另一个是.nm_modname,定义模块的名称,也就是ArkTS侧引入的so库的名称,模块系统会根据此名称来区分不同的so。
- // 准备模块加载相关信息,将上述Init函数与本模块名等信息记录下来。
- static napi_module testModule = {
- .nm_version = 1,
- .nm_flags = 0,
- .nm_filename = nullptr,
- .nm_register_func = Init,
- .nm_modname = "entry",
- .nm_priv = ((void*)0),
- .reserved = { 0 },
- };
-
- // 加载so时,该函数会自动被调用,将上述testModule模块注册到系统中。
- extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
- {
- napi_module_register(&testModule);
- }
实现ArkTS接口与C++接口的绑定和映射。
- EXTERN_C_START
- static napi_value Init(napi_env env, napi_value exports)
- {
- napi_property_descriptor desc[] = {
- { "resultMsg", nullptr, resultMsg, nullptr, nullptr, nullptr, napi_default, nullptr },
- {"setOnCallBack", nullptr, setOnCallBack, nullptr, nullptr, nullptr, napi_default, nullptr},
- {"nativeToTSCallBack", nullptr, nativeToTSCallBack, nullptr, nullptr, nullptr, napi_default, nullptr}
- };
- napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
-
- return exports;
- }
- EXTERN_C_END
- export const resultMsg: (a: number, b: number) => number;
-
- export const setOnCallBack: (cbFn: (progress: number) => void) => void;
-
- export const nativeToTSCallBack: (a: number) => void;
- {
- "name": "libentry.so",
- "types": "./index.d.ts",
- "version": "",
- "description": "Please describe the basic information."
- }
- # the minimum version of CMake.
- cmake_minimum_required(VERSION 3.4.1)
- project(TestC)
-
- set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
-
- if(DEFINED PACKAGE_FIND_FILE)
- include(${PACKAGE_FIND_FILE})
- endif()
-
- include_directories(${NATIVERENDER_ROOT_PATH}
- ${NATIVERENDER_ROOT_PATH}/include)
- # 添加名为entry的库
- add_library(entry SHARED napi_init.cpp)
- # 构建此可执行文件需要链接的库
- target_link_libraries(entry PUBLIC libace_napi.z.so)
- /**
- * 返回测试
- */
- static napi_value resultMsg(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);
-
- napi_valuetype valuetype0;
- napi_typeof(env, args[0], &valuetype0);
-
- napi_valuetype valuetype1;
- napi_typeof(env, args[1], &valuetype1);
-
- double value0;
- napi_get_value_double(env, args[0], &value0);
-
- double value1;
- napi_get_value_double(env, args[1], &value1);
-
- napi_value sum;
- napi_create_double(env, value0 + value1, &sum);
-
- return sum;
-
- }
- Button(this.resultMsg)
- .fontSize(20)
- .fontWeight(FontWeight.Bold)
- .onClick(() => {
- this.add += 1;
- this.resultMsg = `C函数的结果返回,返回结果为:${testNapi.resultMsg(this.add, 3)}`
- })
- /**
- * 设置回调方法
- */
- static napi_value setOnCallBack(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);
- asyncContext->env = env;
- napi_create_reference(env, args[0], 1, &asyncContext->callbackRef);
- return nullptr;
- }
- /**
- * 测试数据回调到TS端展现出来
- */
- static napi_value nativeToTSCallBack(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);
-
- napi_valuetype valuetype0;
- napi_typeof(env, args[0], &valuetype0);
-
- int value0;
- napi_get_value_int32(env, args[0], &value0);
-
- asyncContext->progress = value0;
- std::thread callBackThread(callBackTask);
- callBackThread.detach();
- return nullptr;
-
- }
- aboutToAppear(): void {
- testNapi.setOnCallBack((data: number) => {
- this.callBackMsg = `C函数的结果回调,回调结果为:${data}`
- });
- }
- Button('函数回调测试')
- .fontSize(20)
- .fontWeight(FontWeight.Bold)
- .onClick(() => {
- testNapi.nativeToTSCallBack(1)
- })
- .margin({'top': 50})
- #include "napi/native_api.h"
- #include <thread>
- #include <uv.h>
-
- /**
- * 返回测试
- */
- static napi_value resultMsg(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);
-
- napi_valuetype valuetype0;
- napi_typeof(env, args[0], &valuetype0);
-
- napi_valuetype valuetype1;
- napi_typeof(env, args[1], &valuetype1);
-
- double value0;
- napi_get_value_double(env, args[0], &value0);
-
- double value1;
- napi_get_value_double(env, args[1], &value1);
-
- napi_value sum;
- napi_create_double(env, value0 + value1, &sum);
-
- return sum;
-
- }
-
- typedef struct CallbackContext {
- napi_env env = nullptr;
- napi_ref callbackRef = nullptr;
- int progress = 0;
- } CallbackContext;
-
- auto asyncContext = new CallbackContext();
-
- // 回调ts侧函数,将进度信息通知到ts侧
- static void callTS(napi_env env, napi_value jsCb, void *context, void *data) {
- CallbackContext *arg = (CallbackContext *)data;
- napi_value progress;
- napi_create_int32(arg->env, arg->progress, &progress);
- napi_call_function(arg->env, nullptr, jsCb, 1, &progress, nullptr);
- }
-
- void callBackTask() {
- // 创建线程安全函数
- napi_value workName;
- napi_create_string_utf8(asyncContext->env, "callBack", NAPI_AUTO_LENGTH, &workName);
- napi_value jsCb;
- napi_get_reference_value(asyncContext->env, asyncContext->callbackRef, &jsCb);
- napi_threadsafe_function tsfn;
- napi_create_threadsafe_function(asyncContext->env, jsCb, nullptr, workName, 0, 1, nullptr, nullptr, nullptr, callTS,
- &tsfn);
- while (asyncContext && asyncContext->progress < 10) {
- asyncContext->progress += 1;
- napi_acquire_threadsafe_function(tsfn);
- napi_call_threadsafe_function(tsfn, (void *)asyncContext, napi_tsfn_blocking);
- std::this_thread::sleep_for(std::chrono::milliseconds(100));
- }
- };
-
- /**
- * 设置回调方法
- */
- static napi_value setOnCallBack(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);
- asyncContext->env = env;
- napi_create_reference(env, args[0], 1, &asyncContext->callbackRef);
- return nullptr;
- }
-
- /**
- * 测试数据回调到TS端展现出来
- */
- static napi_value nativeToTSCallBack(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);
-
- napi_valuetype valuetype0;
- napi_typeof(env, args[0], &valuetype0);
-
- int value0;
- napi_get_value_int32(env, args[0], &value0);
-
- asyncContext->progress = value0;
- std::thread callBackThread(callBackTask);
- callBackThread.detach();
- return nullptr;
-
- }
-
- EXTERN_C_START
- static napi_value Init(napi_env env, napi_value exports)
- {
- napi_property_descriptor desc[] = {
- { "resultMsg", nullptr, resultMsg, nullptr, nullptr, nullptr, napi_default, nullptr },
- {"setOnCallBack", nullptr, setOnCallBack, nullptr, nullptr, nullptr, napi_default, nullptr},
- {"nativeToTSCallBack", nullptr, nativeToTSCallBack, nullptr, nullptr, nullptr, napi_default, nullptr}
- };
- napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
-
- return exports;
- }
- EXTERN_C_END
-
- // 准备模块加载相关信息,将上述Init函数与本模块名等信息记录下来。
- static napi_module testModule = {
- .nm_version = 1,
- .nm_flags = 0,
- .nm_filename = nullptr,
- .nm_register_func = Init,
- .nm_modname = "entry",
- .nm_priv = ((void*)0),
- .reserved = { 0 },
- };
-
- // 加载so时,该函数会自动被调用,将上述testModule模块注册到系统中。
- extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
- {
- napi_module_register(&testModule);
- }
参考:
使用Node-API实现跨语言交互开发流程-使用Node-API实现跨语言交互-代码开发-NDK开发-开发 | 华为开发者联盟 (huawei.com)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。