鸿蒙中如何引入使用已经构建好的Native文件

1,016 阅读5分钟

前言

该文章是鸿蒙开发系列文章中的第一篇,该系列文章主要会讲解在Harmony开发中部分常见的一些方案和指导,包括但不限于:

  1. 如何基于C++/Rust等语言开发Native部分的功能
  2. C++如何适配到鸿蒙系统
  3. 如何使用已有的动态链接库等等。

背景

注意:本文需要你在有一定的鸿蒙应用开发基本知识点(了解基本的项目结构和基于ArkTS的基本开发流程)的前提下才能够顺利的完成阅读。

本文的源码在 use-native

在本文开始前,我们先澄清一个常见的问题:

我们可以直接在鸿蒙上使用原来双端或者其他端已经构建好的动态/静态链接库吗?

回答:不可以。

为什么不可以?

这就好比我们想要在iOS上面运行从安卓的NDK构建出来的动态链接库是一个道理,本身由于环境或者native使用问题或者C/C++基础库等一系列问题,导致无法跨系统直接使用。

开始

OK,在这个认知的基础上,我们继续本文的内容。假设我们现在已经有了一个存在的动态链接库文件,名称为: libcrc32.so 该文件提供了两个方法分别如下所示:

import buffer from '@ohos.buffer';

export function crc32(input: string | buffer.Buffer, initialState?: number | undefined | null): number

export function crc32c(input: string | buffer.Buffer, initialState?: number | undefined | null): number

那么我们如何将其在鸿蒙开发的工程中引入呢?

为了确保没有任何环境问题导致使用异常,本文将直接使用推荐方式来引入,我们以新建项目来作为演示。
本文以最新的公开开发环境API9 DevEcoStudio3.1作为开发环境。

项目创建

首先我们需要创建带 Native 的项目。当我们创建这样的项目的时候,我们能够有一个自带的类型声明文件,这对我们能够减少很多额外的工作量。

1.png

目前鸿蒙主要支持三个架构的目标产物,分别为:

  1. arm64-v8a
  2. armeabi-v7a
  3. x86_64

请牢记这三个缩写,这个在以后的鸿蒙Native开发中是常客。

我们的Native的文件也需要分别很对于不同的架构生成不同的产物,不同架构之间不可以混合使用。在日常开发中,有以下两点注意:

  1. 对于现在大部分真机来说,都是arm64-v8a的架构。因此假设我们直接使用真机进行开发的话,我们可以只构建该架构的产物。
  2. 对于部分模拟器可能使用的是不同架构的产物,按需构建即可。

新增文件

现在我们已经创建好了一个新的项目,我们要怎么才能够让鸿蒙构建的时候自动将我们的动态链接库引入到其中呢?

在每个模块中新增libs文件夹,该文件夹下分别有跟上面说到的三个架构同名的文件夹。当应用进行构建的时候,对应架构的应用将会自动将这些文件夹内的动态链接库加载到应用中。

现在我们的libcrc32.so文件想要在应用中加载成功,只需要将其复制到libs/arm64-v8a文件夹中即可。

2.png

解决类型问题

但是这时候,我们仍然无法直接在 ArkTS 的代码中直接引用,此时编辑器会提示我们无法找到对应的模块。

API9的版本校验不强,这里是直接可以进行调用的,更新的版本会直接报错。

这时候我们在刚才说到的类型声明文件就到了它发挥作用的时候了,我们找到cpp目录下的Index.d.ts文件,在其中增加我们的类型定义。

3.png

同时修改当前模块下的oh-package.json5文件,新增如下内容:

4.png

注意:我们这里直接使用了同一个路径文件,这并不影响实际的运行,我们只是简单的复用类型包。如果你觉得有点奇怪的话,也可以复制一个文件夹出来做一些简单的修改来实现。

修改完成之后点击同步,这时候我们就完成了 Native 库的引入,我们可以在代码中直接使用了。

5.png

效果

最终的结果如下所示。

7.png

尾声

这样我们就实现了将一个已经构建完成的动态链接库在鸿蒙应用中直接使用的整个流程。无论是新建项目,还是新建模块还是如何实现,这里最关键的问题在于两点:

  1. 如何让动态库被构建工具一起构建,核心就在模块(entry也是特殊的模块)的libs文件中。
  2. 如何让开发者工具和编译器识别到正确的类型,借助已有的文件或者types字段是关键。

这一部分的内容对于熟练甚至精通鸿蒙开发的小伙伴来说可以说非常简单,但是很多时候是很多初学者被挡住的关键一环。

不过正所谓,难者不会,会者不难。能够解决这个问题之后,将会对我们后续的一些在鸿蒙上面的Native开发有不小的作用。