写点什么

掌握 DevEco Studio 这一功能,高效实现 ArkTS 与 C++ 胶水代码

作者:轻口味
  • 2024-12-18
    北京
  • 本文字数:3105 字

    阅读完需:约 10 分钟

掌握DevEco Studio这一功能,高效实现ArkTS与C++胶水代码

1、背景介绍

HarmonyOS 主要提供了 ArkTS 与 C++作为开发语言:


  • ArkTS 是 HarmonyOS 优选的主力应用开发语言。ArkTS 围绕应用开发在 TypeScript(简称 TS)生态基础上做了进一步扩展,保持了 TS 的基本风格,同时通过规范定义强化开发期静态检查和分析,提升程序执行稳定性和性能。ArkTS 适合用在高效 UI 界面开发场景。

  • C++以 NDK(Native Development Kit)工具集的方式提供支持,NDK 是 HarmonyOS SDK 提供的 Native API、相应编译脚本和编译工具链的集合,方便开发者使用 C 或 C++语言实现应用的关键功能。NDK 只覆盖了 HarmonyOS 一些基础的底层能力,如 C 运行时基础库 libc、图形库、窗口系统、多媒体、压缩库、面向 ArkTS/JS 与 C 跨语言的 Node-API 等,并没有提供 ArkTS/JS API 的完整能力。C++语言适合下方这些场景:

  • 性能敏感的场景,如游戏、物理模拟等计算密集型场景。

  • 需要复用已有 C 或 C++库的场景。

  • 需要针对 CPU 特性进行专项定制库的场景,如 Neon 加速。


有一些能力 HarmonyOS 只提供了 C++接口支持,比如音视频编解码等,而且我们注意到最新发布的 HarmonyOS 5.0.1 版本,新增的能力主要是 C API,所以要挖掘 HarmonyOS 更多能力成为一个资深 HarmonyOS 工程师,ArkTS 与 C++混合开发是必不可少的。


ArkTS 调用 C++需要经过一系列复杂流程,本文主要介绍 DevEco Studio 提供的一键生成跨语言“胶水”代码工具帮助大家提升开发效率。

2、ArkTS 调用 C++方法流程

类似于 Android JNI,HarmonyOS 中 ArkTS 调用 C++方法主要是 NAPI 提供能力。本节以 DevEco Studio 新建的 Native C++工程 Demo 为例介绍 ArkTS 调用 C++方法流程。下图是创建 Native C++工程后的代码结构图:


主要有三大部分组成:


  • types:

  • Index.d.ts:主要包含对 ArkTS 暴露的 C++接口。

  • oh-package.json5:指定动态库名称和上面 Index.d.ts 文件路径。

  • CMakeLists.txt:C++代码构建脚本。

  • napi_init.cpp:C++实现代码


开发 Native 模块一般流程就是要实现上述对应模块。

2.1 Index.d.ts 中声明 C++接口

声明的函数供 C++实现和 ArkTS 中调用


export const add: (a: number, b: number) => number;
复制代码

2.2 C++中注册和实现声明方法

首先在 NAPI 的 Init 方法中注册 Index.d.ts 中声明的方法:


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
复制代码


napi_property_descriptor 是一个数组,可以实现多个方法。示例中字符串"add"表示 Index.d.ts 中声明的 add 方法,第三个参数 Add 表示 C++中实现的方法名。接下来就需要实现 Add 方法:


static napi_value Add(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);        napi_valuetype valuetype0;      napi_typeof(env, args[0], &valuetype0);        napi_valuetype valuetype1;      napi_typeof(env, args[1], &valuetype1);        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;    }
复制代码


NAPI 的实现方法结构是固定的,返回值必须是 napi_value,参数必须是两个 napi_env 与 napi_callback_info,方法中解析 napi_callback_info 具体参数信息实现具体功能。

2.3 CMakelist.txt 中配置编译的动态库名称与 C++源码列表

add_library 指定编译输出的库名称和参与编译的 C++代码列表:


add_library(entry SHARED napi_init.cpp)
复制代码


这方面知识可以参考 CMake 构建工具相关文档:https://cmake.org/

2.4 ArkTS 中调用声明的方法

最后,实现好后就可以在 ArkTS 中调用对应的方法:


//首先导入动态库:import testNapi from 'libentry.so';//调用对应add方法hilog.info(0x0000, 'testTag', 'Test NAPI 2 + 3 = %{public}d', testNapi.add(2, 3));
复制代码

3、DevEco Studio 快速生成胶水代码

从上面 ArkTS 调用 C++方法流程看流程还是有点繁琐,需要在两个文件三处地方做处理,有没有便捷的方法呢?别着急,接下来介绍今天的重头戏,DevEco Studio IDE 提供的跨语言代码编辑


DevEco Studio IDE 提供了两种创建方式:


  1. Index.d.ts 中编写函数声明,一键生成 C++函数

  2. C++头文件编写 C++函数声明,一键生成注册代码


下面分别进行详细介绍。

3.1 Index.d.ts 中编写函数声明,一键生成 C++函数

在 Index.d.ts 中声明方法后,IDE 会提示错误,鼠标悬停后会有下图提示:


点击“Generate native implementation”后即可快捷生成 C++中的注册代码与实现代码:


这样三处手动实现变成了一处,功能还是非常实用,提效不止三分之二。

3.2 C++头文件编写 C++函数声明,一键生成注册代码

通过 C++函数声明一键创建的方式,需要我们先创建一个头文件,然后在头文件中声明方法:


右键该方法,点击生成:


继续点击 NAPI:


注册函数中,以及对应 NAPI 函数实现已经帮助我们完成生成:


![[掌握 DevEco Studio 这一功能,高效实现 ArkTS 与 C++胶水代码-6.png]]Index.d.ts 中的声明方法也已经帮助我们生成:![[掌握 DevEco Studio 这一功能,高效实现 ArkTS 与 C++胶水代码-7.png]]


通过 IDE 的版主,跨语言之间的“胶水”代码编写极大的提高了效率,不得不说,DevEco Studio 提供的这块功能还是相当不错的,很为广大程序员考虑。


这里面需要注意的有三点:


  1. 快捷生成代码的头文件支持类型:.hpp,.hxx,.hh,.h;

  2. 声明的快捷生成 NAPI 的函数当前支持 bool,int,string,void,float,double,std::array,std::vector 等参数类型;

  3. 如果工程中已经创建 napi_init.cpp,则会在文件的 Init 中追加,如果没有创建,IDE 会帮助我们自动创建。

4、借助 AI 提升 C++代码中 NAPI 类型转换代码书写

有了 IDE 提供的自动生成跨语言胶水代码已经极大的帮助我们进行 Native 代码开发,但是可能还有小伙伴感觉生成的 TODO 中的代码也很繁琐,很多 ArkTS 与 C++的跨语言转换代码也很模版和繁琐,有没有对应的提效办法呢?以自动生成的 add 代码为例:


static napi_value Add(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);        napi_valuetype valuetype0;      napi_typeof(env, args[0], &valuetype0);        napi_valuetype valuetype1;      napi_typeof(env, args[1], &valuetype1);        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;    }
复制代码


需要从 napi_callback_info 解析两个 int 类型参数,完成运算后还要继续生成 napi_value 返回。


因为这种跨语言数据类型转换时 NAPI 协议,DevEco CodeGenie 插件也提供了不错的支持,可以在 DevEco Studio 中安装 Genie 插件帮助我们生成快速生成 C++实现代码:


这样,几次“TAB”键后就帮我们生成差不多了,再根据我们业务逻辑实现自己代码即可。

5、总结

本文主要介绍了 Native C++代码的实现步骤,以及 DevEco Studio IDE 提供的跨语言代码编辑工具,实现只写函数声明一键帮助我们生成对应初始化注册方法与 C++实现方法,希望大家多多体验,通过工具提升我们开发效率。

发布于: 刚刚阅读数: 3
用户头像

轻口味

关注

🏆2021年InfoQ写作平台-签约作者 🏆 2017-10-17 加入

Android、音视频、AI相关领域从业者。 欢迎加我微信wodekouwei拉您进InfoQ音视频沟通群 邮箱:qingkouwei@gmail.com

评论

发布
暂无评论
掌握DevEco Studio这一功能,高效实现ArkTS与C++胶水代码_c++_轻口味_InfoQ写作社区