三方库移植之 NAPI 开发 [1]—Hello OpenHarmony NAPI
本文通过一个 Hello OpenHarmony NAPI 样例讲述了 NPAI 接口开发基础知识。开发基于最新的 OpenHarmony3.2Beta3 版本及其对应 SDK。标准系统开发板为润和软件 dayu200。
将 C/C++ 三方库移植到 OpenHarmony 标准系统后,需要通过 NAPI 框架将其 C/C++ 接口转换成 JS/ETS 接口给应用层调用。
通过本文您将熟悉:
如何注册 NAPI 模块及接口。
如何在 ArkUI eTS 代码中调用扩展的 NAPI 接口。
full-SDK 的替换。
什么是 NAPI
NAPI(Native API)组件是一套对外接口基于 Node.js N-API 规范开发的原生模块扩展开发框架。
::: hljs-center
NAPI 组件架构图
:::
OpenHarmony 标准系统应用开发基于 ArkUI 框架,开发语言使用 JS/eTS。部分业务场景依赖使用现有的 C/C++ 库,或为了获取更高的性能。OpenHarmony 提供 NAPI 机制,用于规范封装 IO、CPU 密集型、OS 底层等能力并对外暴露 JS 接口,通过 NAPI 实现 JS 和 C/C++代码的互相访问.
例如: 钟禄平和林嘉诚老师在如何在OpenHarmony上使用SeetaFace2人脸识别库?一文中,重点讲解了 NAPI 接口如何实现 OpenCV 以及 SeetaFace 的调用。一句话概括就是,钟禄平和林嘉诚老师讲述了移植了三方库后通过 NAPI 将库的 C/C++接口变成 JS/ETS 接口给应用层调用。
OpenHarmony 中的 N-API 定义了由 JS/ETS 语言编写的代码和 native 代码(使用 C/C++ 编写)交互的方式,由 Node.js N-API 框架扩展而来。
N-API:Native Application Programming Interface(本地应用程序接接口)
什么是 Node.js N-API 框架 Node.js N-API 为开发者提供了一套 C/C++ API 用于开发 Node.js 的 Native 扩展模块。从 Node.js 8.0.0 开始,N-API 以实验性特性作为 Node.js 本身的一部分被引入,并且从 Node.js 10.0.0 开始正式全面支持 N-API。
添加 OpenHarmony 自定义子系统、组件、模块
这部分内容涉及三方库移植,为便于本篇 NAPI 基础的学习。笔者在此自定义一个子系统用于开发 NAPI。如在已存在的子系统组件中添加扩展 NAPI,则跳过此步。
需要准备好 OpenHarmonyBeta3 源码和编译环境
笔者的编译环境为 WSL2+Ubuntu18.04+vscode,搭建笔者一样的编译环境搭建可以参考 https://ost.51cto.com/posts/17164
添加子系统、组件
直接在 OpenHarmony 源码根目录创建子系统文件夹,取名 mysubsys。并在目录下添加子系统的构建配置文件 ohos.build 完整内容如下:
另外 ohos.build 里面不支持加注释,后面编译的时候会莫名其妙报错。别问,问就是笔者踩过坑了。(好像也没必要加注释)
需要明白以下知识点:
subsystem 后面的 mysubsy 是子系统的名称。
hello 是组件名称,被 mysubsys 子系统包含
hellonapi 是模块名,被 hello 组件包含。
接着将子系统配置到源码下 build\subsystem_config.json 文件,在该文件中插入如下内容。
OpenHarmony 系统架构中,子系统是一个逻辑概念,它具体由对应的组件构成。组件是对子系统的进一步拆分,可复用的软件单元,它包含源码、配置文件、资源文件和编译脚本;能独立构建,以二进制方式集成,具备独立验证能力的二进制单元。
本示例按子系统 system > 组件 part > 组件 module 创建了 3 级目录
源码实现
最后在组件目录下中创建代码文件 hellonapi.cpp
完整内容如下:
代码解析如下:
接口业务实现 C/C++代码
添加 NAPI 接口头文件
NAPI 提供了提供了一系列接口函数,声明包含如下 2 个头文件中,先添加这 2 个头文件到 hellonapi.cpp
native_api.h 和 native_node_api.h 这两个头文件
在 OpenHarmony3.1release 源码中在//foundation/ace/napi/interfaces/kits 目录下
在 OpenHarmony3.2beta3 源码中分别在//foundation/arkui/napi/interfaces/kits 和//foundation/arkui/napi/interfaces/inner_api 目录下了。
注册 NAPI 模块、添加接口声明
定义的 hellonapi 模块,其对应结构体为 napi_module。
指定当前 NAPI 模块对应的模块名
模块注册对外接口的处理函数,具体扩展的接口在该函数中声明。
napi_module_register(napi_module* mod)是 ohos 的 NAPI 组件提供的模块注册函数。
该函数在源码目录下 foundation/arkui/napi/native_engine/native_node.cpp
注册 NAPI 模块总结
自定义子系统构建
hellonapi 编译 gn 化,新增 gn 工程构建脚本。
在模块 hellonapi 目录下新建 BUILD.gn 文件,内容如下:
gn 文件支持注释,以
#
开头
修改产品配置
将组件添加到需要的产品配置文件,源码目录下的 productdefine/common/products/ohos-arm64.json。
插入位置任意,但要注意行尾的逗号,确保格式 json 文件格式正确。
mysubsys 是本示例自定义的子系统名称
hello 是自定义子系统下的组件名称
parts 格式如下:
修改 build/subsystem_config.json
新增子系统定义。
subsystem_config.json 文件定义了有哪些子系统以及这些子系统所在文件夹路径,添加子系统时需要说明子系统 path 与 name,分别表示子系统路径和子系统名。
注意 json 文件也不支持注释!!!
"path": "mysubsys",
表示子系统路径"name": "mysubsys"
表示子系统名称
修改 vendor/hihope/rk3568/config.json 文件
将 mysubsys 子系统添加至 rk3568 开发板,在 vendor 目录下新增产品的定义。
"subsystem": "mysubsys",
表示添加的子系统是 mysubsys"component": "hello",
表示添加的子系统中包含的组件名称是 hello
编译烧录
关于这部分的内容可以参考笔者三方库移植系列文章 https://ost.51cto.com/posts/16848#OpenHarmonySpeexdsp_25
先进行增量编译出子系统的动态库,增量编译没有报错后。再全量编译出镜像,将其烧录到开发板上。
增量编译命令
全量编译和烧录这部分的内容不重复叙述,大家可以参考社区文章 https://ost.51cto.com/posts/16203 镜像文件在源码目录下位置如下:
调用接口
full-SDK 替换(可选)
从 OpenHarmony 3.2 Beta2 起,SDK 会同时提供 Public SDK 和 Full SDK。通过 DevEco Studio 默认获取的 SDK 为 Public SDK。两者差异如下:
Public SDK
面向应用开发者提供,不包含需要使用系统权限的系统接口。通过 DevEco Studio 默认获取的 SDK 为 Public SDK。
Full SDK
面向 OEM 厂商提供,包含了需要使用系统权限的系统接口。使用 Full SDK 时需要手动从镜像站点获取,并在 DevEco Studio 中替换
笔者使用的 DevEco Studio 版本为 3.0.0.993,即 DevEco Studio 3.0。API 为 API9。
full-SDK 替换请参考官方文档: full-SDK替换指南
若提示找不到 npm,需要配置一下环境变量,将以下路径添加到环境变量中即可
D:\DevEco Studio\ohos\sdk\ets\build-tools\ets-loader
创建 OpenHarmony 标准应用
新建项目,选择 OpenHarmony。
compile sdk 选择 9,其他保持默认即可。
插一句题外话,3.1release 版本发布的时候。华为是把 DevEco Studio 分成了 OpenHarmony 和 HarmonyOS 两个版本的,现在又合并到一起了。感兴趣的读者可以查阅笔者文章 https://ost.51cto.com/posts/11168
调用接口
第一步:调用方式和 ArkUI 框架提供的 API 一样,先 import 引入扩展的 NAPI 模块,后直接调用。
index.ets 内容如下:
第二步(可选):参考其他模块的.d.ts 创建扩展模块 @ohos.hellonapi.d.ts 定义文件,放到 IDE 安装 OpenHarmony SDK 的目录路径 ohos\sdk\ets\3.2.7.5\api 下。
.d.ts 文件的命名为 @ohos.ohos_shared_library_name.d.ts,ohos_shared_library 为 BUID.gn 文件中定义的动态库名称
@ohos.hellonapi.d.ts 内容如下:
@since 9
表示 API 的版本为 9@syscap SystemCapability.Ability.AbilityRuntime.AbilityCore
语句在.d.ts 文件中一定要添加,否则 IDE 还是会报错找不到该文件。declare namespace hellonapi
和export default hellonapi
的hellonapi
是 BUILD.gn 中的定义的 ohos_shared_library_name。function getHelloString(): string;
中的getHelloString()
是 hellonapi.cpp 文件中指定的模块注册对外接口的处理函数
则 IDE 扫描如下:
标准应用编译不是强依赖 OpenHarmony SDK,所以可忽略 IDE 中告警,直接编译打包 hap。但是有的时候 IDE 会提示找不到 @ohos.hellonapi.d.ts,然后有小概率的机会无法安装 hap。这个时候就要参考 ohos\sdk\ets\3.2.7.5\api 下的.d.ts 文件编写 @ohos.hellonapi.d.ts 了。如果不新建 @ohos.hellonapi.d.ts 放在 sdk\ets\3.2.7.5\api,则 IDE 会报错
第三步:选择自动签名
第四步:将应用安装到 dayu200 开发板上
运行效果如下:
知识点附送
Native API 中支持的标准库
表 1 OpenHarmony 支持的标准库
评论