OpenHarmony开发者论坛

标题: 学写NAPI子系统 [打印本页]

作者: 深开鸿_王石    时间: 2023-12-22 09:09
标题: 学写NAPI子系统
[md]此篇文章,我们主要是熟悉下NAPI框架,并一起写一个支持NAPI的子系统,这样以后当我们想在hap应用里加自己功能的时候就可以方便的添加。

#### NAPI框架简介

**NAPI(Native API)组件是一套对外接口基于Node.js N-API规范开发的原生模块扩展开发框架。类似于Android的JNI,NAPI框架实现了应用层ts/ets/js语言编写的代码和OpenHarmony的native代码(c/c++)交互的能力。此框架由Node.js N-API框架扩展而来。**

*注意:OpenHarmony的标准系统是采用NAPI框架的,轻量系统则是采用jerryscript框架*

![image.png](https://forums-obs.openharmony.c ... 0fywf6lfils7hss.png "image.png")

![image.png](https://forums-obs.openharmony.c ... r9rwi9qd39yr2bk.png "image.png")

**详细的内容介绍在一下链接内可以看到官方的说明:**

**参考链接:**[https://gitee.com/openharmony/arkui\_napi](https://gitee.com/openharmony/arkui_napi)

#### NAPI的使用

![image.png](https://forums-obs.openharmony.c ... zw2v24qlfkf4v4w.png "image.png")

1. **创建d.ts: @ohos.napitest.d.ts, basic.d.ts**

   * **@ohos.napitest.d.ts是NAPI的声明文件,在DevEco Studio开发的时候会用到d.ts来检查语法和提供代码帮助;**

   ```
   import {AsyncCallback} from './basic';

   /**
    * Provides interfaces to napitest.
    *
    * @since 7
    */
   declare namespace napitest {
     /**
      * Shuts down the system.
      *
      * <p>This method requires the ohos.permission.SHUTDOWN permission.
      *
      * @param reason Indicates the shutdown reason.
      * @systemapi
      * @since 7
      */
     function shutdownDevice(reason: string): void;

     /**
      * Restarts the system.
      *
      * <p>This method requires the ohos.permission.REBOOT permission.
      *
      * @param reason Indicates the restart reason. For example, "updater" indicates entering the updater mode
      * after the restart. If the parameter is not specified, the system enters the normal mode after the restart.
      * @since 7
      */
     function rebootDevice(reason: string): void;

     /**
      * Checks whether the screen of a device is on or off.
      *
      * @return Returns true if the screen is on; returns false otherwise.
      * @since 7
      */
     function isScreenOn(callback: AsyncCallback<boolean>): void;
     function isScreenOn(): Promise<boolean>;
   }
   export default napitest;
   ```

   * **basic.d.ts:一些基础方法的声明**

   ```
   export interface Callback<T> {
       (data: T): void;
   }
     
   export interface ErrorCallback<T extends Error = BusinessError> {
       (err: T): void;
   }

   export interface AsyncCallback<T> {
       (err: BusinessError, data: T): void;
   }

   export interface BusinessError extends Error {
       code: number;
   }
   ```
2. **执行napi\_generator**
   **建立个文件夹,将上面建立的两个d.ts和napi\_generator放在一起**

   ```
   //准备环境
   mkdir napitest
   cd napitest
   vim @ohos.napitest.d.ts
   vim basic.d.ts
   //拷贝napi_generator
   cp [路径]/napi_generator-linux .
   chmod +x napi_generator-linux
   //生成napitest代码
   ./napi_generator-linux -f @ohos.napitest.d.ts -o out
   //当看到success则说明烧录成功

   //检视out目录
   ├── binding.gyp         //工具中间文件
   ├── BUILD.gn            //之后需要用到的gn文件
   ├── napi_gen.log        //工具log
   ├── napitest.cpp        //自动生成的接口调用的实际代码
   ├── napitest.h          //自动生成的接口调用的实际代码
   ├── napitest_middle.cpp //自动生成的napi适配代码
   ├── test.sh             //生成js代码的脚本,官方没给说明,试了下不可用
   ├── tool_utility.cpp    //自动生成的napi适配代码
   └── tool_utility.h      //自动生成的napi适配代码
   ```
3. **建立子系统**

   * **在OpenHarmony源码目录下建立foundation/napitest,将之前生成的文件拷贝到文件夹内**

   ```
   foundation
   ├── ability
   ├── ai
   ├── arkui
   ├── barrierfree
   ├── bundlemanager
   ├── communication
   ├── deviceprofile
   ├── distributeddatamgr
   ├── distributedhardware
   ├── filemanagement
   ├── graphic
   ├── multimedia
   ├── multimodalinput
   ├── napitest
   │   ├── binding.gyp
   │   ├── BUILD.gn
   │   ├── bundle.json
   │   ├── napi_gen.log
   │   ├── napitest.cpp
   │   ├── napitest.h
   │   ├── napitest_middle.cpp
   │   ├── test.sh
   │   ├── tool_utility.cpp
   │   └── tool_utility.h
   ├── resourceschedule
   ```

   * **在目录里创建bundle.json,使用一下内容**

   ```
   {
       "name": "@ohos/napitest",
       "description": "napitest provides atomic capabilities",
       "version": "3.1",
       "license": "Apache License 2.0",
       "publishAs": "code-segment",
       "segment": {
         "destPath": "foundation/napitest"
       },
       "dirs": {},
       "scripts": {},
       "component": {
         //部件名称
         "name": "napitest_interface",
         //子系统名称
         "subsystem": "napitest",
         "features": [],
         "adapted_system_type": [
           "standard"
         ],
         "rom": "10000KB",
         "ram": "10000KB",
         "deps": {
           "components": [
             "ace_napi",
             "ipc_core",
             "libhilog"
           ],
           "third_party": [
             "node"
           ]
         },
         "build": {
           "sub_component": [
             "//foundation/napitest:napitest"
           ],
           "inner_kits": [
             {
               "header": {
                 "header_base": "//foundation/napitest",
                 "header_files": [
                   "tool_utility.h",
                   "napitest.h"
                 ]
               },
               "name": "//foundation/napitest:napitest"
             }
           ]
         }
       }
     }
   ```

   * **为了和bundle.json对应,将BUILD.gn改成如下:**

   ```
   import("//build/ohos.gni")

   ohos_shared_library("napitest")
   {
       sources = [
           "napitest_middle.cpp",
           "napitest.cpp",
           "tool_utility.cpp",
       ]
       include_dirs = [
           ".",
           "//third_party/node/src",
           "//base/hiviewdfx/hilog/interfaces/native/innerkits/include",
       ]
       deps=[
           "//foundation/arkui/napi:ace_napi",
           "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog",
       ]
       remove_configs = [ "//build/config/compiler:no_rtti" ]
       cflags=[
       ]
       cflags_cc=[
           "-frtti",
       ]
       ldflags = [
       ]
       
       relative_install_dir = "module"
       //部件名称
       part_name = "napitest_interface"
       //子系统名称
       subsystem_name = "napitest"
   }
   ```
4. **引入子系统**

   * **增加子系统,修改build/subsystem\_config.json**
     ```
     //在文件后增加
     {
       //前面省略的内容
         ...
       //新增内容
       "napitest": {
         "path": "foundation/napitest",
         "name": "napitest"
       }
     }
     ```
   * **增加编译入口(已目前的master版本为基础,3.2后改过编译路径)**
     ```
     //修改 vendor/hihope/[PRODUCT_NAME]/config.json 文件增加如下行
     {
         "subsystem": "napitest",
         "components": [
         {
             "component": "napitest_interface",
             "features": []
         }
         ]
     },
     ```
5. **编译生成**

   ```
   ./build.sh --product-name PRODUCT_NAME
   //看到success则为编译成功,可以通过find out/[PRODUCT_NAME] -name *napitest.z.so查看生成文件,比如我的文件路径如下:
   ./out/rk3568/lib.unstripped/napitest/napitest_interface/libnapitest.z.so
   ./out/rk3568/napitest/napitest_interface/libnapitest.z.so
   ./out/rk3568/innerkits/ohos-arm/napitest_interface/napitest/libnapitest.z.so
   ./out/rk3568/packages/phone/system/lib/module/libnapitest.z.so
   //最后一个路径就是系统镜像的路径,所以两种办法
   //1,直接copy到板子的/system/lib路径;
   //2,烧录镜像;


   ```

#### 总结

**这样我们就有了自己的subsystem和napi接口,后面的章节我们会讲如何在hap应用里调用系统库**

**参考链接:**[https://gitee.com/openharmony/napi\_generator/tree/master](https://gitee.com/openharmony/napi_generator/tree/master)
[/md]
作者: martin_hu    时间: 2024-8-8 19:29
文中napi_generator-linux从哪获取




欢迎光临 OpenHarmony开发者论坛 (https://forums.openharmony.cn/) Powered by Discuz! X3.5