鸿蒙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_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); }
-
找到与
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 = 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
的话,建议大家去记住一些常用的就行了,对于同一效果的命令有好几条,记住自己顺眼的一条就行