网站内容框架,个人做网站能赚到钱吗,wordpress怎装模板,微信推广怎么弄使用Node-API实现跨语言交互#xff0c;首先需要按照Node-API的机制实现模块的注册和加载等相关动作。 ArkTS/JS侧#xff1a;实现C方法的调用。代码比较简单#xff0c;import一个对应的so库后#xff0c;即可调用C方法。 Native侧#xff1a;.cpp文件#xff0c;实现模…使用Node-API实现跨语言交互首先需要按照Node-API的机制实现模块的注册和加载等相关动作。 ArkTS/JS侧实现C方法的调用。代码比较简单import一个对应的so库后即可调用C方法。 Native侧.cpp文件实现模块的注册。需要提供注册lib库的名称并在注册回调方法中定义接口的映射关系即Native方法及对应的JS/ArkTS接口名称等。
此处以在ArkTS/JS侧实现add()接口、在Native侧实现Add()接口从而实现跨语言交互为例呈现使用Node-API进行跨语言交互的流程。
创建Native C工程
在DevEco Studio中New Create Project选择Native C模板点击Next选择API版本设置好工程名称点击Finish创建得到新工程。创建工程后工程结构可以分两部分cpp部分和ets部分具体可见下文的工程目录介绍。
主要工程目录介绍 entry 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.txtC源码编译配置文件提供CMake构建脚本。entry src main cpp hello.cpp定义C API接口的文件。entry src main ets用于存放ArkTS源码。
Native侧方法的实现 设置模块注册信息 ArkTS侧import native模块时会加载其对应的so。加载so时首先会调用napi_module_register方法将模块注册到系统中并调用模块初始化函数。 napi_module有两个关键属性一个是.nm_register_func定义模块初始化函数另一个是.nm_modname定义模块的名称也就是ArkTS侧引入的so库的名称模块系统会根据此名称来区分不同的so。
// entry/src/main/cpp/hello.cpp// 准备模块加载相关信息将上述Init函数与本模块名等信息记录下来。
static napi_module demoModule {.nm_version 1,.nm_flags 0,.nm_filename nullptr,.nm_register_func Init,.nm_modname entry,.nm_priv nullptr,.reserved {0},
};// 加载so时该函数会自动被调用将上述demoModule模块注册到系统中。
extern C __attribute__((constructor)) void RegisterDemoModule() { napi_module_register(demoModule);}模块初始化 实现ArkTS接口与C接口的绑定和映射。
// entry/src/main/cpp/hello.cpp
EXTERN_C_START
// 模块初始化
static napi_value Init(napi_env env, napi_value exports) {// ArkTS接口与C接口的绑定和映射napi_property_descriptor desc[] {{callNative, nullptr, CallNative, nullptr, nullptr, nullptr, napi_default, nullptr},{nativeCallArkTS, nullptr, NativeCallArkTS, nullptr, nullptr, nullptr, napi_default, nullptr},};// 在exports对象上挂载CallNative/NativeCallArkTS两个Native方法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 nullptr,.reserved {0},
};在index.d.ts文件中提供JS侧的接口方法。
// entry/src/main/cpp/types/libentry/index.d.ts
export const callNative: (a: number, b: number) number;
export const nativeCallArkTS: (cb: (a: number) number) number;在oh-package.json5文件中将index.d.ts与cpp文件关联起来。
{name: libentry.so,types: ./index.d.ts,version: ,description: Please describe the basic information.
}在CMakeLists.txt文件中配置CMake打包参数。
# entry/src/main/cpp/CMakeLists.txt
cmake_minimum_required(VERSION 3.4.1)
project(MyApplication2)set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})include_directories(${NATIVERENDER_ROOT_PATH}${NATIVERENDER_ROOT_PATH}/include)# 添加名为entry的库
add_library(entry SHARED hello.cpp)
# 构建此可执行文件需要链接的库
target_link_libraries(entry PUBLIC libace_napi.z.so)实现Native侧的CallNative以及NativeCallArkTS接口。具体代码如下
// entry/src/main/cpp/hello.cpp
static napi_value CallNative(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 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;
}static napi_value NativeCallArkTS(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);// 创建一个int作为ArkTS的入参napi_value argv nullptr; napi_create_int32(env, 2, argv );// 调用传入的callback并将其结果返回napi_value result nullptr;napi_call_function(env, nullptr, args[0], 1, argv, result);return result;
}ArkTS侧调用C/C方法实现
ArkTS侧通过import引入Native侧包含处理逻辑的so来使用C/C的方法。
// entry/src/main/ets/pages/Index.ets
// 通过import的方式引入Native能力。
import nativeModule from libentry.soEntry
Component
struct Index {State message: string Test Node-API callNative result: ;State message2: string Test Node-API nativeCallArkTS result: ;build() {Row() {Column() {// 第一个按钮调用add方法对应到Native侧的CallNative方法进行两数相加。Text(this.message).fontSize(50).fontWeight(FontWeight.Bold).onClick(() {this.message nativeModule.callNative(2, 3);})// 第二个按钮调用nativeCallArkTS方法对应到Native的NativeCallArkTS在Native调用ArkTS function。Text(this.message2).fontSize(50).fontWeight(FontWeight.Bold).onClick(() {this.message2 nativeModule.nativeCallArkTS((a: number) {return a * 2;});})}.width(100%)}.height(100%)}
}Node-API的约束限制
SO命名规则
导入使用的模块名和注册时的模块名大小写保持一致如模块名为entry则so的名字为libentry.sonapi_module中nm_modname字段应为entryArkTS侧使用时写作import xxx from ‘libentry.so’。
注册建议
nm_register_func对应的函数如上述Init函数需要加上static防止与其他so里的符号冲突模块注册的入口即使用__attribute__((constructor))修饰的函数的函数名如上述RegisterDemoModule函数需要确保不与其它模块重复。
多线程限制
每个引擎实例对应一个JS线程实例上的对象不能跨线程操作否则会引起应用crash。使用时需要遵循如下原则
Node-API接口只能在JS线程使用。Native接口入参env与特定JS线程绑定只能在创建时的线程使用。
为了能让大家更好的学习鸿蒙HarmonyOS NEXT开发技术这边特意整理了《鸿蒙开发学习手册》共计890页希望对大家有所帮助https://qr21.cn/FV7h05
《鸿蒙开发学习手册》
如何快速入门https://qr21.cn/FV7h05
基本概念构建第一个ArkTS应用…… 开发基础知识https://qr21.cn/FV7h05
应用基础知识配置文件应用数据管理应用安全管理应用隐私保护三方应用调用管控机制资源分类与访问学习ArkTS语言…… 基于ArkTS 开发https://qr21.cn/FV7h05
Ability开发UI开发公共事件与通知窗口管理媒体安全网络与链接电话服务数据管理后台任务(Background Task)管理设备管理设备使用信息统计DFX国际化开发折叠屏系列…… 鸿蒙开发面试真题含参考答案https://qr18.cn/F781PH 鸿蒙开发面试大盘集篇共计319页https://qr18.cn/F781PH
1.项目开发必备面试题 2.性能优化方向 3.架构方向 4.鸿蒙开发系统底层方向 5.鸿蒙音视频开发方向 6.鸿蒙车载开发方向 7.鸿蒙南向开发方向