当前位置: 首页 > news >正文

OpenHarmony开发实践-鸿蒙napi开发实践

鸿蒙napi开发实践

前言

HarmonyOS Node-API是基于Node.js 18.x LTS的Node-API规范扩展开发的机制,为开发者提供了ArkTS/JS与C/C++模块之间的交互能力。它提供了一组稳定的、跨平台的API,可以在不同的操作系统上使用。

一般情况下HarmonyOS应用开发使用ArkTS/JS语言,但部分场景由于性能、效率等要求,比如游戏、物理模拟等,需要依赖使用现有的C/C++库。Node-API规范封装了I/O、CPU密集型、OS底层等能力并对外暴露C接口,使用C/C++模块的注册机制,向ArkTS/JS对象上挂载属性和方法的方式来实现ArkTS/JS和C/C++的交互。主要场景如下:

  • 系统可以将框架层丰富的模块功能通过Node-API的模块注册机制对外暴露ArkTS/JS的接口,将C/C++的能力开放给应用的ArkTS/JS层。

  • 应用开发者也可以选择将一些对性能、底层系统调用有要求的核心功能用C/C++封装实现,再通过ArkTS/JS接口使用,提高应用本身的执行效率。

开发步骤
第一步:创建Native C++工程
  • 在DevEco Studio中New > Create Project,选择Native C++模板,点击Next,选择API版本,设置好工程名称,点击Finish,创建得到新工程。、

在这里插入图片描述

  • 创建工程后工程结构可以分两部分,cpp部分和ets部分

    目录结构如下:
    在这里插入图片描述

    entry:应用模块,编译构建生成一个HAP。

  • src > main > cpp > types:用于存放C++的API接口描述文件

  • src > main > cpp > types > libentry > index.d.ts:描述C++ API接口行为,如接口名、入参、返回参数等。

  • src > main > cpp > types > libentry> oh-package.json5:配置.so三方包声明文件的入口及包名。

  • src > main > cpp > CMakeLists.txt:CMake配置文件,提供CMake构建脚本。

  • src > main > cpp > napi_init.cpp:定义C++ API接口的文件

  • **src > main > ets:**用于存放ArkTS源码。

native侧的实现

设置模块注册信息

ArkTS侧import native模块时,会加载其对应的so。加载so时,首先会调用napi_module_register方法,将模块注册到系统中,并调用模块初始化函数。

napi_module有两个关键属性:一个是.nm_register_func,定义模块初始化函数;另一个是.nm_modname,定义模块的名称,也就是ArkTS侧引入的so库的名称,模块系统会根据此名称来区分不同的so。

我们对napi_init.cpp文件的代码进行解析

#include "napi/native_api.h"// 定义 N-API 函数 Add:接收两个数字参数,返回它们的和(N-API 标准静态函数声明)
// env:N-API 环境句柄(用于访问所有 N-API 函数)
// info:回调信息句柄(包含函数调用时的参数、this 指针等上下文)
static napi_value Add(napi_env env, napi_callback_info info)
{// 1. 初始化参数相关变量size_t argc = 2;                  // 期望接收的参数个数(此处为 2 个数字)napi_value args[2] = {nullptr};   // 存储传入参数的数组(napi_value 是 N-API 中所有值的通用类型)// 2. 获取函数调用时的实际参数// 作用:从 info 中提取参数到 args 数组,同时更新实际接收的参数个数到 argc// 参数说明:env(环境句柄)、info(回调信息)、&argc(实际参数个数输出)、args(参数存储数组)、//          nullptr(不获取 this 指针)、nullptr(不获取额外数据)napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);// 3. (可选,此处仅获取类型未做校验)获取两个参数的数据类型napi_valuetype valuetype0;  // 存储第一个参数的数据类型(如数字、字符串等)napi_typeof(env, args[0], &valuetype0);  // 获取 args[0] 的数据类型napi_valuetype valuetype1;  // 存储第二个参数的数据类型napi_typeof(env, args[1], &valuetype1);  // 获取 args[1] 的数据类型// 4. 将 N-API 数值(napi_value)转换为 C 语言的 double 类型double value0;  // 存储第一个参数的 double 值// 作用:将 args[0](N-API 数值)解析为 double 并写入 value0napi_get_value_double(env, args[0], &value0);double value1;  // 存储第二个参数的 double 值napi_get_value_double(env, args[1], &value1);  // 解析 args[1] 为 double// 5. 计算总和并转换为 N-API 数值类型napi_value sum;  // 存储结果的 N-API 数值// 作用:创建一个新的 N-API 双精度数值(value0 + value1),并写入 sumnapi_create_double(env, value0 + value1, &sum);// 6. 返回计算结果(N-API 函数必须返回 napi_value 类型)return sum;
}
// 模块初始化
EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports)
{napi_property_descriptor desc[] = {{ "add", nullptr, Add, 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 demoModule = {.nm_version = 1,.nm_flags = 0,.nm_filename = nullptr,.nm_register_func = Init,.nm_modname = "entry",.nm_priv = ((void*)0),.reserved = { 0 },
};
// 加载so时,该函数会自动被调用,将上述demoModule模块注册到系统中
extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
{napi_module_register(&demoModule);
}

我们在napi_init.cpp中定义了一个add的方法,然后我们需要在Index.d.ts中暴露出去

export const add: (a: number, b: number) => number;
ArkTS中调用
import { hilog } from '@kit.PerformanceAnalysisKit';
//引入napi的so库
import testNapi1 from 'libentry.so';const DOMAIN = 0x0000;@Entry
@Component
struct Index {@State message: string = 'Hello World';build() {Row() {Column() {Text(this.message).fontSize($r('app.float.page_text_font_size')).fontWeight(FontWeight.Bold).onClick(() => {this.message = 'Welcome';//调用即可hilog.info(DOMAIN, 'testTag', 'Test NAPI 2 + 3 = %{public}d', testNapi1.add(2, 3));})}.width('100%')}.height('100%')}
}

其中在entry模块中引用so库,是在oh-package.json5中配置napi的依赖路径,配置代码如下

{"name": "entry","version": "1.0.0","description": "Please describe the basic information.","main": "","author": "","license": "","dependencies": {"libentry.so": "file:./src/main/cpp/types/libentry"}
}

手动配置时,需要把鼠标放到路径下,ohpm install 一下,安装一下依赖

至此,我们就可以分两部分,napi和ArkTS各自开发各自的功能

欢迎大家跟我一起学习鸿蒙开发知识,加入我的班级,参与HarmonyOS赋能资源丰富度建设(第四期)-夏文强,获得HarmonyOS应用开发者认证 每月对前200名学员进行激励,活动期间共计激励1000名

华为开发者学堂

http://www.dtcms.com/a/573988.html

相关文章:

  • Redis识别缓存与数据库数据的不一致性以及识别热Key教程
  • 网站运营培训机构网站建设是做什么的
  • 商丘网站建设专业现状网站首页布局
  • 28.DHCP
  • Linux基础指令-Linux学习笔记(1)
  • 可以推广网站市网站制作
  • STM32TIM定时器PWM1模式与PWM2模式配置
  • 阿勒泰建设局网站北京模板网站建设费用
  • 上传OSS直传
  • 网站正在建设中页面 英文翻译网络网站建设电话
  • 外企渣打内推
  • TGRS 即插即用 | 超越传统U-Net!ASCNet融合小波变换与全局注意力,重新定义图像修复范式
  • 一线城市网站建设费用高wordpress调用id数据
  • BOD5快速测定仪:环境水质监测的高效解决方案
  • 【仓颉纪元】仓颉性能优化深度实战:5 天让应用提速 300%
  • 全网营销型网站建设公司wordpress 个人soho
  • Python 正则表达式实战 + 详解:从匹配QQ邮箱到掌握核心语法
  • 五度易链产业大脑技术拆解:AI + 大数据 + 云计算如何构建产业链数字基础设施?
  • 湖南如何做网络营销seo哪家好
  • 松北建设局网站网件路由器为什么都是官翻
  • 【Unity】接入腾讯TimPush通知消息推送
  • 使用WinBoat在Linux中安装window应用
  • 文档抽取技术:通过自然语言处理自动提取简历中的结构化信息,实现高效人才筛选
  • 蓝奥声EID+ECWAN架构:构建设备跨域用电数据无损迁移体系
  • 打车/网约车、代驾、顺风车/拼车、货运、租车等多种出行服务的一站式解决方案
  • MQTT协议
  • 网站开发设计培训价格建筑网建设通查询
  • 正规的网站建设官网环保类网站建设
  • 做电影资讯网站算侵权吗wordpress comment_form
  • 想在公司局域网做建网站全渠道运营平台系统