开天辟地 HarmonyOS(鸿蒙) - Native Development Kit: NDK 基础
开天辟地 HarmonyOS(鸿蒙) - Native Development Kit: NDK 基础
示例如下:
pages\ndk\NdkDemo.ets
/*
* NDK 基础
* 详见 /ndk1/src/main/ets/pages/NdkDemo.ets
*/
import { TitleBar } from '../TitleBar';
import { common, Want } from '@kit.AbilityKit';
@Entry
@Component
struct NdkDemo {
context = getContext() as common.UIAbilityContext;
build() {
Column() {
TitleBar()
Button("打开 ndk 演示页面").onClick(() => {
let want: Want = {
bundleName: 'com.webabcd.harmonydemo',
moduleName: 'ndk1',
abilityName: 'com.webabcd.harmonydemo.Ndk1Ability',
};
this.context.startAbility(want);
})
}
}
}
\ndk1\src\main\ets\pages\NdkDemo.ets
/*
* NDK - Native Development Kit
* ABI - Application Binary Interface
* NAPI - Node API(用于提供 ArkTS 与 c/c++ 之间的交互能力)
*
* 源码方式引用本地的 ndk 模块时,需要在 oh-package.json5 中做类似如下的配置
* {
* "dependencies": {
* "libndk1.so": "file:./src/main/cpp/types/libndk1"
* }
* }
*
* 编译 ndk 项目需要在 build-profile 中做类似如下的配置
* {
* "buildOption": {
* "externalNativeOptions": {
* "path": "./src/main/cpp/CMakeLists.txt", // cmake 文件地址
* "abiFilters": ["arm64-v8a", "x86_64"], // 指定编译架构
* }
* },
* }
*/
// 导入 .so
import testNapi from 'libndk1.so';
import { TitleBar } from './TitleBar';
@Entry
@Component
struct NdkDemo {
@State message: string = 'hello ndk';
build() {
Column({space:10}) {
TitleBar()
Text(this.message)
Button("使用 .so 计算 2 + 3").onClick(() => {
this.message = `2 + 3 = ${testNapi.add(2, 3)}`
})
}
}
}
\ndk1\src\main\cpp\napi_init.cpp
/*
* NDK - Native Development Kit
* ABI - Application Binary Interface
* NAPI - Node API(用于提供 ArkTS 与 c/c++ 之间的交互能力)
*/
// 提供本地开发所需的接口和类型定义
#include "napi/native_api.h"
// 在 c/c++ 中定义一个名为 MyAdd 的函数
static napi_value MyAdd(napi_env env, napi_callback_info info)
{
// 用于说明 MyAdd 函数的参数的个数为 2 个
size_t argc = 2;
// 用于定义一个长度为 2 的 napi_value 数组
napi_value args[2] = {nullptr};
// 将 2 个参数保存在 args 数组中
napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);
// 将第 1 个参数转换为 c/c++ 的 double 类型,并将此值保存在 value0 中
double value0;
napi_get_value_double(env, args[0], &value0);
// 将第 2 个参数转换为 c/c++ 的 double 类型,并将此值保存在 value1 中
double value1;
napi_get_value_double(env, args[1], &value1);
// 执行 value0 + value1 并将结果保存在 sum 中
napi_value sum;
napi_create_double(env, value0 + value1, &sum);
return sum;
}
// 确保 c++ 代码以 c 链接方式编译,用于解决 c++ 和 c 之间的兼容性问题
EXTERN_C_START
// 注册导出内容
static napi_value Init(napi_env env, napi_value exports)
{
// 将 c/c++ 的名为的 MyAdd 函数导出为 arkts 的名为 add 的函数
napi_property_descriptor desc[] = {
{ "add", nullptr, MyAdd, nullptr, nullptr, nullptr, napi_default, nullptr }
};
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
return exports;
}
EXTERN_C_END
// 注册当前的 NAPI 模块
static napi_module demoModule = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = Init,
.nm_modname = "ndk1",
.nm_priv = ((void*)0),
.reserved = { 0 },
};
extern "C" __attribute__((constructor)) void RegisterNdk1Module(void)
{
napi_module_register(&demoModule);
}
\ndk1\src\main\cpp\CMakeLists.txt
# 指定构建此项目所需的 CMake 的最低版本为 3.5.0
cmake_minimum_required(VERSION 3.5.0)
# 定义项目名称
project(HarmonyDemo)
# 定义一个变量,并赋值为当前 CMake 文件所在目录
set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
# 添加头文件 .h 目录,用于告诉 cmake 去这里找代码引入的头文件
include_directories(${NATIVERENDER_ROOT_PATH}
${NATIVERENDER_ROOT_PATH}/include)
# 生成一个名为 ndk1 的动态链接库(比如 .so 文件),源文件为 napi_init.cpp
# 生成的 .so 文件的名称为 libndk1.so,其要与 libndk1/oh-package.json5 中的 name 一致
add_library(ndk1 SHARED napi_init.cpp)
# 将动态链接库 ndk1 链接到 libace_napi.z.so 库(libace_napi.z.so 是 OpenHarmony 的 NAPI 接口实现)
target_link_libraries(ndk1 PUBLIC libace_napi.z.so)
\ndk1\src\main\cpp\types\libndk1\Index.d.ts
// .d.ts 是类型声明文件,用于帮助 TypeScript 编译器理解 .so 中导出的函数和变量(此文件的路径是在 oh-package.json5 中的 types 标签配置的)
// 以本例来说,此处的 add 函数要与 napi_init.cpp 中的导出内容一致
export const add: (a: number, b: number) => number;
\ndk1\src\main\cpp\types\libndk1\oh-package.json5
{
"name": "libndk1.so", // .so 的名称,要与 CMakeLists.txt 中的 add_library() 中指定的名称一致
"types": "./Index.d.ts", // 指定类型声明文件,其用于帮助 TypeScript 编译器理解 libndk1.so 中导出的函数和变量
"version": "1.0.0",
"description": "Please describe the basic information."
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步