当前位置: 首页 > article >正文

鸿蒙Native使用Demo

DevecoStudio使用Native

今天,给大家带来的是关于DevecoStudio中使用Native进行开发

个人拙见:为什么要使用Native?无论是JS还是TS在复杂的情况下运行速度,肯定不如直接操作内存的C/C++的运行速度快,所以,会选择使用Native;这里面的过程是什么?通过映射转化,使用napi提供的接口调用CMake后的C/C++的函数

个人代码–点我

第一步-建立Native项目

image-20241126104203994

第二步-去建立自己的demo

  1. 找到该路径src/main/cpp,再该路径下建一个demo

  2. demo包下依次建立include包,src包,CMakeLists.txt文件

  3. 准备一些测试文件

    1. include目录–存放.h头文件

      #ifndef _HEAD_H
      #define _HEAD_H
      // 加法
      int add(int a, int b);
      // 减法
      int subtract(int a, int b);
      // 乘法
      int multiply(int a, int b);
      // 除法
      double divide(int a, int b);
      #endif
      
    2. src目录–存放.cpp文件

      #include <iostream>
      #include "../include/head.h"
      
      using namespace std;
      
      int add(int a,int b){
          return a+b;
      }
      
      #include <iostream>
      #include "../include/head.h"
      
      using namespace std;
      
      double divide(int a, int b) { return a / b; }
      
      #include <iostream>
      #include "../include/head.h"
      
      using namespace std;
      
      int main() {
          int a = 20;
          int b = 12;
          printf("a = %d, b = %d\n", a, b);
          printf("a + b = %d\n", add(a, b));
          printf("a - b = %d\n", subtract(a, b));
          printf("a * b = %d\n", multiply(a, b));
          printf("a / b = %f\n", divide(a, b));
          return 0;
      }
      
      #include <iostream>
      #include "../include/head.h"
      
      using namespace std;
      
      int multiply(int a, int b) { return a * b; }
      
      #include <iostream>
      #include "../include/head.h"
      
      using namespace std;
      
      int subtract(int a, int b) { return a - b; }    
      
  4. 编写CMakeLists.txt

    cmake_minimum_required(VERSION 3.5.0)
    project(demo1)
    # 添加头文件搜索路径,包括当前目录和 include 子目录
    include_directories(${CMAKE_CURRENT_SOURCE_DIR}
    ${CMAKE_CURRENT_SOURCE_DIR}/include)
    # 收集 src 目录下所有的 .cpp 文件,存储到 SRC_LIST 变量中
    file(GLOB SRC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
    # 添加库文件搜索路径
    link_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib)
    # 使用收集到的源文件创建一个名为 calc 的共享库
    add_library(calc SHARED ${SRC_LIST})
    

第三步-在ets文件中运行自己的demo接口

在上面,我们已经写好了自己的demo接口,下面,就去看如何运行这个demo的接口

  1. 找到napi_init.cpp文件

    1. image-20241126105355420

    2. 文件修改如下

      #include "napi/native_api.h"
      #include "demo/include/head.h" // demo头文件
      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, add(value0, value1), &sum);
      
          return sum;
      }
      // demo接口
      static napi_value NAPI_Global_sub(napi_env env, napi_callback_info info) {
          // TODO: implements the code;
          // 声明接受两个参数
          size_t argc = 2;
          napi_value args[2] = {nullptr}; // 用在存放JS对象在内存中的位置  类似于*void
      
          // testNapi.sub(2, 3)
          napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
      
          // get的方法都是用来把js类型转换成C++数据类型
          double value0;
          napi_get_value_double(env, args[0], &value0);
      
          double value1;
          napi_get_value_double(env, args[1], &value1);
      
      
          // value0 + value1 这里是C++里面的类型
          // create方法都是用来创建JS数据类型
          napi_value sub;
          napi_create_double(env, subtract(value0, value1), &sub);
      
          return sub;
      }
      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},
              {"sub", nullptr, NAPI_Global_sub, nullptr, nullptr, nullptr, napi_default, nullptr}}; // 定义导出的demo函数
          napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
          return exports;
      }
      EXTERN_C_END
      
      static napi_module demoModule = {
          .nm_version = 1,
          .nm_flags = 0,
          .nm_filename = nullptr,
          .nm_register_func = Init,
          .nm_modname = "entry",
          .nm_priv = ((void *)0),
          .reserved = {0},
      };
      
      extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }
      
    3. 找到与demo同级目录下的CMakeLists.txt文件

      1. image-20241126105626623

      2. 添加demo子目录到构建系统,并连接demo生成的库文件calc

        # the minimum version of CMake.
        cmake_minimum_required(VERSION 3.5.0)
        project(NativeDemo)
        
        # 设置变量 NATIVERENDER_ROOT_PATH 为当前源代码目录的路径
        set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
        
        if(DEFINED PACKAGE_FIND_FILE)
            include(${PACKAGE_FIND_FILE})
        endif()
        
        include_directories(${NATIVERENDER_ROOT_PATH}
                            ${NATIVERENDER_ROOT_PATH}/include)
        
        # 创建一个名为 entry 的共享库,源文件是 napi_init.cpp
        add_library(entry SHARED napi_init.cpp)
        # 添加 demo 子目录到构建系统
        add_subdirectory(demo)
        # 将 libace_napi.z.so 和 calc 库链接到 entry 库
        target_link_libraries(entry PUBLIC libace_napi.z.so calc)
        
    4. 接下来修改,暴露出的接口Index.d.ts文件

      1. image-20241126105907878

      2. 添加我们在napi_init.cpp中添加的接口(演示的话,为了方便只添加一个)

        export const add: (a: number, b: number) => number;
        export const sub: (a: number, b: number) => number;
        
    5. 大家可以尝试运行一下了–以下是成功运行情况

image-20241126110943133

  1. 调用

    import { hilog } from '@kit.PerformanceAnalysisKit';
    import DemoNapi from 'libentry.so'; // 包名自定义,没有影响
    
    @Entry
    @Component
    struct Index {
      @State a:number = 0
      @State b:number = 0
    
      @State result1:number = 0
      @State result2:number = 0
    
      build() {
        Column({space:10}) {
          Row(){
            Text('NAPI初体验-四则运算器')
              .textAlign(TextAlign.Center)
              .fontSize(25)
          }
          .width("100%")
          .justifyContent(FlexAlign.Center)
    
          Row({space:10}){
            TextInput({placeholder:'请输入第一个数'})
              .onChange((value)=>{
                this.a = parseInt(value)
              })
              .type(InputType.Number)
              .width(100)
            TextInput({placeholder:'请输入第二个数'})
              .onChange((value)=>{
                this.b = parseInt(value)
              })
              .type(InputType.Number)
              .width(100)
          }
          .width('100%')
          .justifyContent(FlexAlign.Center)
    
          Button('计算')
            .onClick(()=>{
              this.result1 = DemoNapi.add(this.a,this.b)
              this.result2 = DemoNapi.sub(this.a,this.b)
              hilog.info(0x0000, 'testTag', 'Test NAPI 2 + 3 = %{public}d', DemoNapi.add(2, 3));
              hilog.info(0x0000, 'testTag', 'Test NAPI 2 - 3 = %{public}d', DemoNapi.sub(2, 3));
            })
    
          Text(`加法结果为:${this.result1}`)
            .fontSize(30)
            .fontWeight(FontWeight.Bold)
          Text(`减法结果为:${this.result2}`)
            .fontSize(30)
            .fontWeight(FontWeight.Bold)
        }
        .width('100%')
        .height('100%')
      }
    }
    

总结

以上,大家就可以简单的使用Native了,关于CMakeLists.txt的话,建议大家去记住一些常用的就行了,对于同一效果的命令有好几条,记住自己顺眼的一条就行


http://www.kler.cn/a/412295.html

相关文章:

  • Next.js 独立开发教程(八):静态渲染与动态渲染的应用
  • 爬虫开发(5)如何写一个CSDN热门榜爬虫小程序
  • 腾讯云OCR车牌识别实践:从图片上传到车牌识别
  • Scrapy图解工作流程-cnblog
  • 什么是MyBatis?
  • CentOS8.5.2111(7)完整的Apache综合实验
  • ubuntu使用Docker,安装,删除,改源等记录
  • 类的加载机制
  • 自制Windows系统(十)
  • Unity 设计模式-单例模式(Singleton)详解
  • 【大数据学习 | Spark-Core】Spark中的join原理
  • 双向链表、循环链表、栈
  • Docker desktop 改变存储位置
  • VUE练习
  • Hive的基础函数
  • 英语知识在线平台:Spring Boot技术探索
  • 流媒体拥塞控制与流控
  • 几个bev模型部署常用的命令
  • 深度学习每周学习总结J6(ResNeXt-50 算法实战与解析 - 猴痘识别)
  • Spring MVC练习(前后端分离开发实例)
  • Linux -线程互斥与同步
  • qt QDateTime详解
  • 【书生大模型实战营第四期】评测 InternLM-1.8B 实践
  • LSA详情与特殊区域
  • Pydantic 数据验证
  • 1- 9 C 语言面向对象