在 OpenHarmony 系统上,ArkTS 具备完整广泛的生态,为复用 ArkTS 生态,仓颉支持与 ArkTS 高效跨语言互通。
仓颉-ArkTS 互操作基于仓颉 CFFI 能力,通过调用 ArkTS 运行时接口,为用户提供库级别的 ArkTS 互操作能力。
使用场景:
- 在 ArkTS 应用开发仓颉模块:把用户仓颉代码封装成为 ArkTS 模块,能够被 ArkTS 代码加载和调用。
- 在仓颉应用里使用 ArkTS 存量库:在仓颉代码里创建新的 ArkTS 运行时,并加载和执行 ArkTS 的字节码。
互操作库的主要组成和功能:
- JSValue: 统一的 ArkTS 数据类型,在跨语言调用中做传参,对 ArkTS 类型做判断和做数据转换。
- JSContext: 一个 ArkTS 互操作上下文,用户创建 ArkTS 数据,辅助把 JSValue 转换为仓颉数据。
- JSCallInfo: 一次 ArkTS 函数调用的参数集合,包含所有的入参和 this 指针。
- JSRuntime: 一个由仓颉创建的 ArkTS 运行时。
在 ArkTS 应用里开发仓颉模块
开发仓颉互操作模块:
-
【仓颉侧】导入互操作库。
import ohos.ark_interop.*
-
【仓颉侧】定义要导出的函数,可被 ArkTS 调用的仓颉函数的类型是固定的:(JSContext, JSCallInfo)->JSValue。
func addNumber(context: JSContext, callInfo: JSCallInfo): JSValue { // 从 JSCallInfo 获取参数列表 let arg0: JSValue = callInfo[0] let arg1: JSValue = callInfo[1] // 把 JSValue 转换为仓颉类型 let a: Float64 = arg0.toNumber() let b: Float64 = arg1.toNumber() // 实际仓颉函数行为 let value = a + b // 把结果转换为 JSValue let result: JSValue = context.number(value).toJSValue() // 返回 JSValue return result }
-
【仓颉侧】注册要导出的函数。
// 类名没有影响 class Main { // 定义静态构造函数(也可用全局变量和静态变量的初始化表达式触发) static init() { // 注册键值对 JSModule.registerModule {context, exports => exports["addNumber"] = context.function(addNumber).toJSValue() } } }
-
【ArkTS 侧】导入 ark_interop_loader,这是一个在 ohos-sdk 中提供的 napi 模块,作为仓颉运行时的启动器和仓颉模块的加载器。
import {requireCJLib} from "libark_interop_loader.so"
-
【ArkTS 侧】定义仓颉库导出的接口。
interface CangjieLib { // 定义的仓颉互操作函数,名称与仓颉侧注册名称一致。一般先定义 ArkTS 函数声明,在实现仓颉函数时根据声明来解析参数和返回。 addNumber(a: number, b: number): number; }
-
【ArkTS 侧】导入和调用仓颉库。
// 导入仓颉库,仓颉模块默认编译产物是 libentry_default.so,用户可以在 cjpm.toml 中修改配置。 const cjLib = requireCJLib("libentry_default.so") as CangjieLib; // 调用仓颉接口 let result = cjLib.addNumber(1, 2); console.log(`1 + 2 = ${result}`);
在仓颉应用里使用 ArkTS 模块
ArkTS 模块的编译产物主要有两种:
- C 代码(+ArkTS)编译成 so。
- 纯 ArkTS 代码编译成 abc。
加载 ArkTS so 模块
ArkTS so 模块根据部署方式的不同,分为以下几种:
- 随系统发布,在镜像的/system/lib64/module目录下。
- 随应用(hap)发布,在应用的/libs/arm64-v8a目录下,安装后在设备上的全局路径(通过hdc shell观察到的路径):/data/app/el1/bundle/public/${bundleName}/libs/arm64、沙箱路径(运行时可访问路径):/data/storage/el1/bundle/libs/arm64。
- 随动态库(hsp)发布。
这里主要介绍怎么加载随系统发布的 so 模块,这些 so 在 OpenHarmony 的官方文档里会有开发文档。
接下来以相册管理模块作为示例,详细的介绍加载流程。
-
查看 ArkTS 文档,其导入模块的范本如下。
import photoAccessHe