鸿蒙Native使用Demo
DevecoStudio使用Native
今天,给大家带来的是关于
DevecoStudio
中使用Native
进行开发个人拙见:为什么要使用
Native
?无论是JS
还是TS
在复杂的情况下运行速度,肯定不如直接操作内存的C/C++
的运行速度快,所以,会选择使用Native
;这里面的过程是什么?通过映射转化,使用napi提供的接口调用CMake
后的C/C++
的函数个人代码–点我
第一步-建立Native项目
第二步-去建立自己的demo
-
找到该路径
src/main/cpp
,再该路径下建一个demo
包 -
在
demo
包下依次建立include
包,src
包,CMakeLists.txt
文件 -
准备一些测试文件
-
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
-
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; }
-
-
编写
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的接口
-
找到
napi_init.cpp
文件-
-
文件修改如下
#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_ENDstatic 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); }
-
找到与
demo
同级目录下的CMakeLists.txt
文件-
-
添加
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)
-
-
接下来修改,暴露出的接口
Index.d.ts
文件-
-
添加我们在
napi_init.cpp
中添加的接口(演示的话,为了方便只添加一个)export const add: (a: number, b: number) => number; export const sub: (a: number, b: number) => number;
-
-
大家可以尝试运行一下了–以下是成功运行情况
-
-
调用
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 = 0build() {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
的话,建议大家去记住一些常用的就行了,对于同一效果的命令有好几条,记住自己顺眼的一条就行
相关文章:

鸿蒙Native使用Demo
DevecoStudio使用Native 今天,给大家带来的是关于DevecoStudio中使用Native进行开发 个人拙见:为什么要使用Native?无论是JS还是TS在复杂的情况下运行速度,肯定不如直接操作内存的C/C的运行速度快,所以,会选择使用Native;这里面的过程是什么?通过映射转化,使用napi提供的接口…...

29.UE5蓝图的网络通讯,多人自定义事件,变量同步
3-9 蓝图的网络通讯、多人自定义事件、变量同步_哔哩哔哩_bilibili 目录 1.网络通讯 1.1玩家Pawn之间的同步 1.2事件同步 1.3UI同步 1.4组播 1.5变量同步 1.网络通讯 1.1玩家Pawn之间的同步 创建一个第三人称项目 将网络模式更改为监听服务器,即将房主作为…...

Scala—列表(可变ListBuffer、不可变List)用法详解
Scala集合概述-链接 大家可以点击上方链接,先对Scala的集合有一个整体的概念🤣🤣🤣 在 Scala 中,列表(List)分为不可变列表(List)和可变列表(ListBuffer&…...

【论文复现】偏标记学习+图像分类
📝个人主页🌹:Eternity._ 🌹🌹期待您的关注 🌹🌹 ❀ 偏标记学习图像分类 概述算法原理核心逻辑效果演示使用方式参考文献 概述 本文复现论文 Progressive Identification of True Labels for Pa…...

C嘎嘎探索篇:栈与队列的交响:C++中的结构艺术
C嘎嘎探索篇:栈与队列的交响:C中的结构艺术 前言: 小编在之前刚完成了C中栈和队列(stack和queue)的讲解,忘记的小伙伴可以去我上一篇文章看一眼的,今天小编将会带领大家吹奏栈和队列的交响&am…...

AIGC-----AIGC在虚拟现实中的应用前景
AIGC在虚拟现实中的应用前景 引言 随着人工智能生成内容(AIGC)的快速发展,虚拟现实(VR)技术的应用也迎来了新的契机。AIGC与VR的结合为创造沉浸式体验带来了全新的可能性,这种组合不仅极大地降低了VR内容的…...

Django 路由层
1. 路由基础概念 URLconf (URL 配置):Django 的路由系统是基于 urls.py 文件定义的。路径匹配:通过模式匹配 URL,并将请求传递给对应的视图处理函数。命名路由:每个路由可以定义一个名称,用于反向解析。 2. 基本路由配…...

《硬件架构的艺术》笔记(八):消抖技术
简介 在电子设备中两个金属触点随着触点的断开闭合便产生了多个信号,这就是抖动。 消抖是用来确保每一次断开或闭合触点时只有一个信号起作用的硬件设备或软件。(就是每次断开闭合只对应一个操作)。 抖动在某些模拟和逻辑电路中可能产生问…...

Spring 与 Spring MVC 与 Spring Boot三者之间的区别与联系
一.什么是Spring?它解决了什么问题? 1.1什么是Spring? Spring,一般指代的是Spring Framework 它是一个开源的应用程序框架,提供了一个简易的开发方式,通过这种开发方式,将避免那些可能致使代码…...

【算法】连通块问题(C/C++)
目录 连通块问题 解决思路 步骤: 初始化: DFS函数: 复杂度分析 代码实现(C) 题目链接:2060. 奶牛选美 - AcWing题库 解题思路: AC代码: 题目链接:687. 扫雷 -…...

如何选择黑白相机和彩色相机
我们在选择成像解决方案时黑白相机很容易被忽略,因为许多新相机提供鲜艳的颜色,鲜明的对比度和改进的弱光性能。然而,有许多应用,选择黑白相机将是更好的选择,因为他们产生更清晰的图像,更好的分辨率&#…...

Rust 力扣 - 740. 删除并获得点数
文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 首先对于这题我们如果将所有点数装入一个切片f中,该切片f中的i号下标表示所有点数为i的点数之和 那么这题就转换成了打家劫舍这道题,也就是求选择了切片中某个下标的元素后,该…...

OpenCV从入门到精通实战(七)——探索图像处理:自定义滤波与OpenCV卷积核
本文主要介绍如何使用Python和OpenCV库通过卷积操作来应用不同的图像滤波效果。主要分为几个步骤:图像的读取与处理、自定义卷积函数的实现、不同卷积核的应用,以及结果的展示。 卷积 在图像处理中,卷积是一种重要的操作,它通过…...

Docker核心概念总结
本文只是对 Docker 的概念做了较为详细的介绍,并不涉及一些像 Docker 环境的安装以及 Docker 的一些常见操作和命令。 容器介绍 Docker 是世界领先的软件容器平台,所以想要搞懂 Docker 的概念我们必须先从容器开始说起。 什么是容器? 先来看看容器较为…...
环形缓冲区
什么是环形缓冲区 环形缓冲区,也称为循环缓冲区或环形队列,是一种特殊的FIFO(先进先出)数据结构。它使用一块固定大小的内存空间来缓存数据,并通过两个指针(读指针和写指针)来管理数据的读写。当任意一个指针到达缓冲区末尾时,会自动回绕到缓冲区开头,形成一个"环"。…...

jQuery-Word-Export 使用记录及完整修正文件下载 jquery.wordexport.js
参考资料: jQuery-Word-Export导出word_jquery.wordexport.js下载-CSDN博客 近期又需要自己做个 Html2Doc 的解决方案,因为客户又不想要 Html2pdf 的下载了,当初还给我费尽心思解决Html转pdf时中文输出的问题(html转pdf文件下载之…...

云服务器部署WebSocket项目
WebSocket是一种在单个TCP连接上进行全双工通信的协议,其设计的目的是在Web浏览器和Web服务器之间进行实时通信(实时Web) WebSocket协议的优点包括: 1. 更高效的网络利用率:与HTTP相比,WebSocket的握手只…...
C#+数据库 实现动态权限设置
将权限信息存储在数据库中,支持动态调整。根据用户所属的角色、特定的功能模块,动态加载权限” 1. 数据库设计 根据这种需求,可以通过以下表设计: 用户表 (Users):存储用户信息。角色表 (Roles):存储角色…...

(原创)Android Studio新老界面UI切换及老版本下载地址
前言 这两天下载了一个新版的Android Studio,发现整个界面都发生了很大改动: 新的界面的一些设置可参考一些博客: Android Studio新版UI常用设置 但是对于一些急着开发的小伙伴来说,没有时间去适应,那么怎么办呢&am…...

Ubuntu24虚拟机-gnome-boxes
推荐使用gnome-boxes, virtualbox构建失败,multipass需要开启防火墙 sudo apt install gnome-boxes创建完毕~...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...