OpenHarmony系统之Napi框架生成工具介绍 原创 精华

深开鸿
发布于 2023-12-26 09:41
浏览
1收藏

作者:苟晶晶

前言

当开发者为OpenHarmony系统上开发JS与C++交互的接口时,需要使用NAPI进行接口封装:首先需要用户定义JS接口,然后创建NAPI模块、实现NAPI初始化函数、封装JS接口、处理JS调用,最后进行构建和部署。这需要开发人员熟悉NAPI,有一定的学习成本。而Napi框架生成工具可以根据用户指定路径下的ts(typescript)接口文件一键生成NAPI框架代码、业务代码框架,这为开发者提供了一种快速、高效的开发方式,可以大大提高开发效率。使用该工具时,开发者不必关注Nodejs的语法、C++与JS之间的数据类型转换等上层应用逻辑,只需要关注底层业务逻辑;此外,Napi框架生成工具还可以自动生成GN文件,这样就可以方便地将生成的代码集成到OpenHarmony系统中。这种方式可以避免手动编写GN文件的繁琐过程,提高了代码集成的效率。

1.使用说明

NAPI框架生成工具支持三种入口,分别是可执行程序、VS Code插件、DevEco Studio上使用的IntelliJ插件,使用者可以根据自己的需要选择合适的工具。本文主要介绍可执行文件的使用方法。

1.可执行文件下载路径如下(由于网络原因,可能会导致有的下载链接失效,因此提供了以下三个下载链接):

可执行文件下载链接1

可执行文件下载链接2

可执行文件下载链接3

访问密码:kaihong

压缩包解压密码:kaihong20231121

准备

输入文件说明

1.待转换的示例.ts文件 @ohos.napitest.d.ts

declare namespace napitest {
    function func1(v: string): string;
}
export default napitest;

2.业务代码serviceCode示例

业务代码头文件Service.h

#ifndef IMPL_SERVICE_H
#define IMPL_SERVICE_H

#include <string>

namespace napitest {
    std::string func1(std::string& v);
}
#endif // IMPL_SERVICE_H

业务代码cpp文件Service.cpp

#include "Service.h"
#include "../generatorCode/napitest.h"
#include "hilog/log.h"
static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0XD002E00, "NAPITESTNAPILayer"};
#define NAPITEST_LOGI(fmt, ...) OHOS::HiviewDFX::HiLog::Info(LABEL, \
    	"%{public}s:%{public}d " fmt, __func__, __LINE__, ##__VA_ARGS__)
	
namespace napitest {
std::string func1(std::string& v)
{
    NAPITEST_LOGI("NAPITEST_LOGI func1 v = %s\r\n", v.c_str());  // 打印输入参数
    return "testzzz";
}
}

3.配置文件cfg.json示例

[
  {
    "includeName": "../serviceCode/Service.h",
    "cppName": "../serviceCode/Service.cpp",
    "interfaceName": "func1",
    "serviceCode": "out = napitest::func1(v);"
  }
]

可执行文件使用方法

Linux

1.将待转换的.d.ts文件(如@ohos.napitest.d.ts)、napi_generator-linux、 配置文件cfg.json、业务代码文件夹serviceCode(其中serviceCode目录下放置业务代码的.h文件和.cpp文件)放在同级目录下。此处新建generatorCode文件夹,用于存放生成框架代码。整体目录文件如下:

OpenHarmony@Ubuntu-64:~/service$ ls
napi_generator-linux  @ohos.napitest.d.ts  generatorCode  cfg.json  serviceCode

2.在终端中进入到之前可执行程序napi_generator-linux所在的目录,并运行napi_generator-linux,命令如下:

OpenHarmony@Ubuntu-64:~/service$ ./napi_generator-linux -f @ohos.napitest.d.ts -o generatorCode -i false -n int -s cfg.json

其中,参数详情如下:

-f, 待转换的.d.ts文件,若同时转换多个文件,文件之间用“,”隔开;

-d, 根据指定路径转换该文件夹中所有.d.ts文件;

-i, 可选参数,默认false,待转换.d.ts文件中引用非basic.d.ts的ts文件时打开开关;

-o, 可选参数,默认为当前目录,指定生成框架代码输出路径;

-n, 可选参数,默认为uint32_t,指定生成框架代码中number类型全部为指定类型;

-s, 可选参数,默认为不配置业务代码,指定生成框架代码的业务配置文件,用于粘合工具代码和业务代码的配置。

备注1:-f与-d两个参数只选其中一个参数即可。

备注2:若.d.ts文件中声明了basic.d.ts文件,将basic.d.ts文件放置在待转换.d.ts文件同一级目录;若除此之外还声明其它.d.ts文件,将此类文件放置在待转换.d.ts文件同级目录。

其中,cfg.json内容如下:

[
 {
  "includeName": "../serviceCode/Service.h",
  "cppName": "../serviceCode/Service.cpp",
  "interfaceName": "func1",
  "serviceCode": "out = napitest::func1(v);",
  "description": "includeName: 引入的业务代码.h文件相对路径, cppName: 引入的业务代码.cpp文件相对路径, interfaceName: ts文件中的使用接口名,业务代码就在该接口中调用;格式为:类名::方法名(如: TestClass::funcTest1),若无类名,则格式为:方法名(如: funcTest), serviceCode: 在接口中调用业务代码的调用语句。(该属性只做注释使用)"
 }
]

cfg.json是一个数组,每一项配置对应一个方法的调用,需要对多少方法进行调用就配置多少项;其中

“includeName”: 引入的业务代码.h文件相对路径, 如: “…/serviceCode/Service.h”,

“cppName”: 引入的业务代码.cpp文件相对路径, 如:“…/serviceCode/Service.cpp”,

“interfaceName”: ts文件中的使用接口名,业务代码就在该接口中调用;格式为:类名::方法名(如: TestClass::funcTest1),若无类名,则格式为:方法名(如: func1),

“serviceCode”: 在接口中调用业务代码的调用语句。此处调用的是实现该接口的业务代码, 如:“out = napitest::func1(v);”

“description”: 仅作为cfg.json文件中描述其它字段含义的属性,用户配置时,可以不用填写这个字段

3.运行成功后会在generatorCode目录下生成框架代码文件,如下所示:

OpenHarmony@Ubuntu-64:~/linshi/napi_generator_8/examples/ts/generatorCode$ ls
binding.gyp  BUILD.gn  napi_gen.log  napitest.cpp  napitest.h  napitest_middle.h napitest_middle.cpp  test.sh  tool_utility.cpp  tool_utility.h

Windows

1.将待转换的.d.ts文件(如@ohos.napitest.d.ts)、napi_generator-win.exe、 配置文件cfg.json、业务代码文件夹serviceCode(其中serviceCode目录下放置业务代码的.h文件和.cpp文件)放在同级目录下。此处新建generatorCode文件夹,用于存放生成框架代码。整体目录文件如下:

E:\demo\napi>dir /B
@ohos.napitest.d.ts
napi_generator-win.exe
generatorCode
cfg.json
serviceCode

2.在终端中进入到之前可执行程序napi_generator-win.exe所在的目录,并运行napi_generator-win.exe,命令如下:

E:\demo\napi>napi_generator-win.exe -f @ohos.napitest.d.ts -o generatorCode -i false -n double -s cfg.json

其中,参数详情如下:

-f, 待转换的.d.ts文件,若同时转换多个文件,文件之间用“,”隔开;

-d, 根据指定路径转换该文件夹中所有.d.ts文件;

-i, 可选参数,默认false,待转换.d.ts文件中引用非basic.d.ts的ts文件时打开开关;

-o, 可选参数,默认为当前目录,指定生成框架代码输出路径;

-n, 可选参数,默认为uint32_t,指定生成框架代码中number类型全部为指定类型;

-s, 可选参数,默认为不配置业务代码,指定生成框架代码的业务配置文件,用于粘合工具代码和业务代码的配置。

备注1:-f与-d两个参数只选其中一个参数即可。

备注2:若.d.ts文件中声明了basic.d.ts文件,将basic.d.ts文件放置在待转换.d.ts文件同一级目录;若除此之外还声明其它.d.ts文件,将此类文件放置在待转换.d.ts文件同级目录。

其中,cfg.json内容如下:

[
 {
  "includeName": "../serviceCode/Service.h",
  "cppName": "../serviceCode/Service.cpp",
  "interfaceName": "func1",
  "serviceCode": "out = napitest::func1(v);",
  "description": "includeName: 引入的业务代码.h文件相对路径, cppName: 引入的业务代码.cpp文件相对路径, interfaceName: ts文件中的使用接口名,业务代码就在该接口中调用;格式为:类名::方法名(如: TestClass::funcTest1),若无类名,则格式为:方法名(如: funcTest), serviceCode: 在接口中调用业务代码的调用语句。(该属性只做注释使用)"
 }
]

cfg.json是一个数组,每一项配置对应一个方法的调用,需要对多少方法进行调用就配置多少项;其中

“includeName”: 引入的业务代码.h文件相对路径, 如: “…/serviceCode/Service.h”,

“cppName”: 引入的业务代码.cpp文件相对路径, 如:“…/serviceCode/Service.cpp”,

“interfaceName”: ts文件中的使用接口名,业务代码就在该接口中调用;格式为:类名::方法名(如: TestClass::funcTest1),若无类名,则格式为:方法名(如: func1),

“serviceCode”: 在接口中调用业务代码的调用语句。此处调用的是实现该接口的业务代码, 如:“out = napitest::func1(v);”

“description”: 仅作为cfg.json文件中描述其它字段含义的属性,用户配置时,可以不用填写这个字段

3.运行成功后会在generatorCode目录下生成框架代码文件,如下所示:

E:\demo\napi\generatorCode>dir /B
binding.gyp
BUILD.gn
napitest.cpp
napitest.h
napitest_middle.h
napitest_middle.cpp
napi_gen.log
test.sh
tool_utility.cpp
tool_utility.h

Mac

方法步骤参考windows、Linux的使用方法。

不配置cfg.json文件生成框架代码

若使用配置文件配置业务代码不能满足用户使用场景需求,可手动配置业务代码,参考以下链接:

不配置cfg.json生成框架代码说明

输出文件说明

Napi工具生成文件如下所示:

binding.gyp
BUILD.gn
napitest.cpp
napitest.h
napitest_middle.h
napitest_middle.cpp
napi_gen.log
test.sh
tool_utility.cpp
tool_utility.h

其中binding.gyp为工具生成框架代码后自测时的编译配置文件;BUILD.gn为集成到OpenHarmony系统上的编译配置文件;napitest.h和napitest.cpp是工具生成的业务代码文件,业务开发者在这里对业务接口进行调用或进行业务代码实现;而napitest_middle.h,napitest_middle.cpp,tool_utility.h,tool_utility.cpp为胶水代码,即NAPI框架代码,用于创建NAPI模块、实现NAPI初始化函数、参数转换、封装JS接口、处理JS调用等;napi_gen.log为工具生成的日志文件。

2.集成说明

本集成说明针对的是OpenHarmony 4.0release系统,其他系统可能存在差别,开发者可自行调试修改。

用户使用配置文件cfg.json生成框架代码后,不必再手动修改业务代码,直接将生成代码集成到OpenHarmony的方法参考以下链接:

生成代码集成到OpenHarmony

若在生成框架代码时,用户未选择配置文件cfg.json生成框架代码,那么在集成时用户就需要在生成的框架代码中自行添加业务代码,例如当前ts文件生成的napitest.cpp文件,修改相应代码后如下所示:

#include "napitest.h"
#include "hilog/log.h"
static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0XD002E00, "NAPITESTNAPILayer"};
#define NAPITEST_LOGI(fmt, ...) OHOS::HiviewDFX::HiLog::Info(LABEL, \
    	"%{public}s:%{public}d " fmt, __func__, __LINE__, ##__VA_ARGS__)
	
namespace napitest {
bool func1(std::string& v, std::string& out)
{
    NAPITEST_LOGI("NAPITEST_LOGI func1 v = %s\r\n", v.c_str());  // 打印输入参数
    out = "testzzz";
    return true;
}
}

手动配置业务代码之后集成到OpenHarmony的方法参考以下链接:

4.0版本手动配置业务代码集成方法

3.应用测试

准备

1.硬件:rk3568开发套件。

2.系统镜像: 集成到OpenHarmony并编译成功的镜像,路径如下:

OpenHarmony/out/rk3568/packages/phone/images

3.扩展SDK接口并增加新接口调用

​ 3.1 扩展SDK接口

​ 查看SDK目录:

OpenHarmony系统之Napi框架生成工具介绍-鸿蒙开发者社区

​ 将@ohos.napitest.d.ts文件拷贝到sdk目录下的ets\api:

OpenHarmony系统之Napi框架生成工具介绍-鸿蒙开发者社区

​ 3.2 编写应用测试新接口

​ 其中修改index.ets文件内容如下:

	import hilog from '@ohos.hilog';
	import napitest from '@ohos.napitest';
	
	@Entry
	@Component
	struct Index {
	  @State message: string = 'Hello World'
	
	  build() {
	    Row() {
	      Column() {
	        Text(this.message)
	          .fontSize(50)
	          .fontWeight(FontWeight.Bold)
	        // 添加按钮,以响应用户点击
	        Button() {
	          Text('TEST')
	            .fontSize(30)
	            .fontWeight(FontWeight.Bold)
	        }
	        .type(ButtonType.Capsule)
	        .margin({
	          top: 20
	        })
	        .backgroundColor('#0D9FFB')
	        .width('40%')
	        .height('5%')
	        // 跳转按钮响应
	        .onClick(() => {
	          let out = napitest.func1("abcf");
	          hilog.info(0x0000, 'testTag', '%{public}s', 'AAAAAAAA napi testprint' + out);
	        })
	      }
	      .width('100%')
	    }
	    .height('100%')
	  }
	}

使用说明

步骤一:安装镜像环境:将out/rk3568/packages/phone目录下的images镜像文件下载并烧录到开发板上。

 OpenHarmony@Ubuntu-64:~/OpenHarmony/out/rk3568/packages/phone/images$ ll
 total 767452
 drwxrwxrwx  2 root root       4096 Nov 21 05:32 ./
 drwxrwxrwx 15 root root       4096 Nov 21 05:32 ../
 -rwxrwxrwx  1 root root   67108864 Nov 21 05:04 boot_linux.img*
 -rw-r--r--  1 root root   52428800 Nov 21 05:32 chip_prod.img
 -rwxrwxrwx  1 root root       8569 Nov 21 05:04 config.cfg*
 -rw-r--r--  1 root root   12582912 Nov 21 05:32 eng_system.img
 -rwxrwxrwx  1 root root     455104 Nov 21 05:04 MiniLoaderAll.bin*
 -rwxrwxrwx  1 root root        756 Nov 21 05:04 parameter.txt*
 -rw-rw-r--  1 root root    2507625 Nov 21 05:32 ramdisk.img
 -rwxrwxrwx  1 root root    5639680 Nov 21 05:04 resource.img*
 -rw-r--r--  1 root root   52428800 Nov 21 05:32 sys_prod.img
 -rw-r--r--  1 root root 1610608640 Nov 21 05:32 system.img
 -rwxrwxrwx  1 root root    4194304 Nov 21 05:04 uboot.img*
 -rw-rw-r--  1 root root   15806303 Nov 21 05:32 updater.img
 -rw-r--r--  1 root root 1468006400 Nov 21 05:32 userdata.img
 -rw-r--r--  1 root root  268431360 Nov 21 05:32 vendor.img

步骤二:安装hap包。

Build Haps通过后,通过Run按钮将hap包安装到板子上。

执行完成后,设备中会出现安装的APP。

步骤三:打印日志并验证结果。

hap包安装成功后,进入hdc shell

首先执行以下命令关闭hilog隐私权限

hilog -p off

输入命输入命令实时打印日志并输出至windows中。

.\hdc.exe hilog > log.txt

然后单击设备中安装的APP,进入APP后单击测试按钮,执行完成后会在hdc安装目录下出现log.txt文件。

查看结果

log.txt中包含“AAAAAAAA napi testprint testzzz”日志表示接口调用成功。如下所示:

// 打印js层传递给C++的入参abcf
I C02e00/NAPITESTNAPILayer: [Service.cpp:10] NAPITEST_LOGI func1 v = abcf
// 打印接口返回到js的返回值testzzz
01-01 08:10:55.571  2291  2291 I A00000/testTag: AAAAAAAA napi testprint testzzz

使用问题

问题:用可执行程序生成C++代码失败,log如下所示:

E:\napi_generator_aboutTest\zzx_gjj_napi230808\napiTest>napi_generator-win.exe -f @ohos.napitest.d.ts
at checkGenerate [C:\snapshot\napi_generator\src\gen\cmd_gen.js(135:21)] @ohos.napitest.d.ts (15,41): Cannot find module './basic'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option?

fail
@ohos.napitest.d.ts (15,41): Cannot find module './basic'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option?

问题定位:@ohos.napitest.d.ts依赖了文件basic.d.ts,但在@ohos.napitest.d.ts同级目录下未找到该依赖文件。

Cannot find module './basic'.

解决方案:将依赖文件basic.d.ts放在@ohos.napitest.d.ts同级目录下,若@ohos.napitest.d.ts中还引用了其他依赖文件,需要一一将其加入到其依赖的路径下。

更多常见问题解决方法指导如下:

FAQ

相关仓

关于Napi工具,若想了解更多,请参考以下链接:

napi_generator: NAPI框架生成工具

总结

Napi框架生成工具是一个开源项目,我们欢迎有兴趣的开发者试用该工具,并提出宝贵的改进意见,我们将继续不断优化和完善该工具软件。我们相信,该工具会成为OpenHarmony生态圈中一个有用的补充。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
1
收藏 1
回复
举报
2条回复
按时间正序
/
按时间倒序
wx5c2e0eef7a16b
wx5c2e0eef7a16b

你好我发现该工具生成的框架只能存储一个回调函数,怎么样能存储多个回调,而不会只存储最后一个回调呢?

回复
2024-1-5 10:29:53
物联风景
物联风景

不错不错,挺好的!

回复
2024-1-8 10:57:33
回复
    相关推荐