【开源三方库】Aki:一行代码极简体验JS&C++跨语言交互

199 篇文章 0 订阅
198 篇文章 0 订阅

前言

Aki——针对OpenHarmony上提供JS与C/C++跨语言互调的场景提供解决方案,提供了复杂度仅为O(1)级别的极简语法糖使用方式,一行代码完成JS与C/C++的无障碍跨语言互调,所键即所得。同时开发者无需关心NAPI的线程安全问题、Native对象GC问题,为开发者屏蔽NAPI内部复杂逻辑。
image.png

OpenHarmony中NAPI的用法不在本文阐述,不然就有点像孔乙己“茴香豆有几种写法”的感觉了。感兴趣的可以参考OpenHarmony关于Native API使用指导。而开发者使用NAPI过程中还会发现:为了做跨线程任务,需要做线程管理,需要关心环境上下文;为了使用结构体对象,需要关注napi_value生命周期如何管理;巴拉巴拉等等与自己业务无关的逻辑。搞了半天,发现业务代码一行没写,还在写NAPI的跨语言调用实现。拥有洁癖的开发者还会发现,很难做到隔离NAPI代码与业务代码,我们讨厌毫无边界性的编程

二、所键即所得:NAPI的尽头就是Aki

image.png

归根结底NAPI要做的就是FFI即跨语言调用,而开发者重视的是自己的业务逻辑而不是如何做跨语言调用:我就想把大象放进冰箱,你非要告诉我:先打开冰箱,然后抬起大象放进去,再关上冰箱。开发者想要的就是直截了当指明这个函数是个跨语言调用函数。Aki提供了JSBind语法糖,就做了这么一件事,开发者集成后,完全做到一行代码:所键即所得,并把业务代码与FFI代码完美隔离,提供了友好的边界性编程体验。
示例一:同步异步接口封装
示例一期望将C++业务逻辑(GetName)注册为JS同步接口(getSync)、异步接口(getAsync),Aki提供了极简的JSBind函数绑定语法糖,一行代码绑定跨语言调用接口:
● C/C++ Code

#include <aki/jsbind.h>

// C++业务逻辑
std::string GetName(std::string key)
{
    std::string result = ...... // 获取数据的业务逻辑

    return result; // 返回字符串类型
}

// Aki JSBind语法糖
JSBIND_ADDON(task_runner);
JSBIND_GLOBAL() {
    JSBIND_FUNCTION(GetName, "getNameSync"); // 绑定同步方法
    JSBIND_PFUNCTION(GetName, "getNameAsync"); // 绑定异步方法
}

● JavaScript Code

import libtask_runner from 'libtask_runner.so';

const name = libstorage.getNameSync('name');// 调用同步方法
console.log('name is ' + name);

// 调用异步方法
libstorage.getNameAsync('name').then(date => {
    console.log('name is ' + data);
}).catch(error => {
    console.log('error: ' + error);
});

示例二:Native与JS对象绑定
示例二期望将C++结构体/类对象(Person)逻辑注册为JS类对象(Person),包含类构造函数+类成员函数+类静态函数+类属性访问等特性,通知支持类对象作为参数及返回值。Aki提供了极简的JSBind对象绑定语法糖,开发者无需关注Native对象内存与JS引擎GC垃圾回收关系,直接绑定Native对象:
● C/C++ Code

#include <aki/jsbind.h>

// C++逻辑
struct Person {
    // 构造函数,用于JS侧 new 对象
    Person(std::string name) : name(name) {}

    // 静态函数
    static Person GetAllPerson(); // 支持类对象作为参数

    // 成员函数
    int SayHello();

    std::string name;
};

// Aki JSBind语法糖
JSBIND_ADDON(person);
JSBIND_CLASS(Person) {
    JSBIND_CONSTRUCTOR<std::string>(); // 绑定构造函数
    JSBIND_METHOD(GetAllPerson); // 绑定类静态函数
    JSBIND_METHOD(SayHello); // 绑定类成员函数
    JSBIND_PROPERTY(name); // 绑定类成员属性
}

● JavaScript Code


import libperson from 'libperson.so';

let person = new libperson.Person("aki"); // 调用构造函数
console.log('person name: ' + person.name); // 访问类属性
let greeting = person.SayHello(); // 调用类成员函数
let persons = libperson.Person.GetAllPerson(); // 调用类静态函数

示例三:在非JS线程中回调JS接口
示例三期望在非JS线程中回调JS接口,Aki提供了线程安全的JSBind语法糖,开发者无需关注JS线程安全问题——OpenHarmony方舟引擎规定JS回调的任务必须抛到JS线程中才能执行,否则会出现崩溃(即Native侧只能在JS线程使用NAPI)。
● C/C++ Code

#include <aki/jsbind.h>

// C++逻辑
void SafetyCallback(std::function<void (std::string)> callback) {
    std::thread t([callback = std::move(callback)] () {
        callback("aki"); // 线程安全,直接调用
    });
    t.detach();
}

// Aki JSBind语法糖
JSBIND_ADDON(sub_thread);
JSBIND_GLOBAL() {
    JSBIND_FUNCTION(SafetyCallback);
}

● JavaScript Code

import libsub_thread from 'libsub_thread.so';
// 入参为JS方法回调
libsub_thread.SafetyCallback((data) => {
  console.error('test result = ' + data); // test result = aki
})

示例四:Native调用绑定JS函数
示例四期望在C/C++侧调用JS接口(非回调)创建rdb关系型数据库表。Aki提供了JS侧的内建JSBind语法糖,开发者可直接绑定JS侧函数供Native侧调用。
● JavaScript Code

import libAddon from 'libaddon.so'

function createTable(table: string) {
    rdbStore.executeSql()... // OHOS 关系型数据库逻辑
}

libAddon.JSBind.bindFunction('createTable', createTable); // 绑定JS函数

● C/C++ Code

#include <aki/jsbind.h>

// C++逻辑
bool DoSomethingFromNative() {
    if (auto createTable = aki::JSBind::GetJSFunction("createTable")) {
        createTable->Invoke<void>("MYSTORE"); // 入参类型 string
    }

示例五:类型转换

Aki支持丰富的类型转换,几乎所有JS的数据类型都可以通过Aki映射为同等的C/C++数据类型,开发者无需处理类型转换,如上述示例用法,框架支持自动匹配类型转换,下表为当前支持的完整类型转换关系:

image.png

三、集成依赖Aki

1.创建平台工程DevEco Studio 创建包含Native C++的工程

File > New > Create Project | Module

2.配置依赖并安装● ohpm三方组件依赖:@ohos/aki指定模块路径下(如:项目根路径/entry),输入如下命令安装ohpm har包依赖:

cd entry
ohpm install @ohos/aki

CMakeLists.txt添加依赖:

...
set(AKI_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules/@ohos/aki) # 设置AKI根路径
set(CMAKE_MODULE_PATH ${AKI_ROOT_PATH})
find_package(Aki REQUIRED)
...
target_link_libraries(${YOUR_TARGET} PUBLIC Aki::libjsbind) # 链接二进制依赖
...

● 源码依赖用户自定义路径下(如:项目根路径/entry/src/main/cpp),输入如下命令下载源码:

cd entry/src/main/cpp
git clone https://gitee.com/openharmony-sig/aki.git

CMakeLists.txt添加依赖:

...
add_subdirectory(aki)
target_link_libraries(entry PUBLIC aki_jsbind) // entry 为编译目标
...

3.编译工程&运行
完成!!!

写在最后

有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)文档用来跟着学习是非常有必要的。

这份鸿蒙(HarmonyOS NEXT)文档包含了鸿蒙开发必掌握的核心知识要点,内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony南向开发、鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)技术知识点。

希望这一份鸿蒙学习文档能够给大家带来帮助,有需要的小伙伴自行领取,限时开源,先到先得~无套路领取!!

获取这份完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习文档

鸿蒙(HarmonyOS NEXT)5.0最新学习路线

在这里插入图片描述

有了路线图,怎么能没有学习文档呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开发入门教学视频,内容包含:ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。

获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习文档

《鸿蒙 (OpenHarmony)开发入门教学视频》

在这里插入图片描述

《鸿蒙生态应用开发V3.0白皮书》

在这里插入图片描述

《鸿蒙 (OpenHarmony)开发基础到实战手册》

OpenHarmony北向、南向开发环境搭建

在这里插入图片描述

《鸿蒙开发基础》

●ArkTS语言
●安装DevEco Studio
●运用你的第一个ArkTS应用
●ArkUI声明式UI开发
.……
在这里插入图片描述

《鸿蒙开发进阶》

●Stage模型入门
●网络管理
●数据管理
●电话服务
●分布式应用开发
●通知与窗口管理
●多媒体技术
●安全技能
●任务管理
●WebGL
●国际化开发
●应用测试
●DFX面向未来设计
●鸿蒙系统移植和裁剪定制
……
在这里插入图片描述

《鸿蒙进阶实战》

●ArkTS实践
●UIAbility应用
●网络案例
……
在这里插入图片描述

获取以上完整鸿蒙HarmonyOS学习文档,请点击→纯血版全套鸿蒙HarmonyOS学习文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值