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

OpenHarmony:NDK开发

一:概述

NDK(Native Development Kit)是HarmonyOS SDK提供的Native API、相应编译脚本和编译工具链的集合,方便开发者使用C或C++语言实现应用的关键功能。NDK只覆盖了HarmonyOS一些基础的底层能力,如C运行时基础库libc、图形库、窗口系统、多媒体、压缩库、面向ArkTS/JS与C跨语言的Node-API等,没有提供ArkTS/JS API的完整能力。

运行态,开发者可以使用NDK中的Node-API接口,访问、创建、操作JS对象;也允许JS对象使用Native动态库。

本章将以led为例开发一个可供ArkTS调用的Native调用库。

其中Node-API详细可见官网:

https://developer.huawei.com/consumer/cn/doc/harmonyos-references/napihttps://developer.huawei.com/consumer/cn/doc/harmonyos-references/napi

二:工程创建

创建一个Native C++工程:该工程会创建一个NDK开发的完整框架,包含一个加法运算的demo。

Index.ets经过上一章app开发已经不陌生了,该小节重点对cpp目录下的文件进行说明:

napi_led.cpp:Native API实现的具体文件,后续会详细说明。

CMakeLists.txt:通过DevEco Studio模板工程创建的NDK工程中,包含默认生成的CMakeLists.txt脚本,如下所示:

# the minimum version of CMake.
cmake_minimum_required(VERSION 3.5.0)
project(UnitTestPro)# 定义一个变量,并赋值为当前模块cpp目录
set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})if(DEFINED PACKAGE_FIND_FILE)include(${PACKAGE_FIND_FILE})
endif()# 添加头文件.h目录,包括cpp,cpp/include,告诉cmake去这里找到代码引入的头文件
include_directories(${NATIVERENDER_ROOT_PATH}${NATIVERENDER_ROOT_PATH}/include)# 声明一个产物libled.so,SHARED表示产物为动态库,napi_led.cpp为产物的源代码
add_library(led SHARED napi_led.cpp)# 声明产物led链接时需要的三方库libace_napi.z.so
# 这里直接写三方库的名称是因为它是在ndk中,已在链接寻址路径中,无需额外声明
target_link_libraries(led PUBLIC libace_napi.z.so libhilog_ndk.z.so)

oh-package.json5:Native侧配置文件

{"name": "libled.so","types": "./Index.d.ts","version": "1.0.0","description": "Please describe the basic information."
}

Index.d.ts:Native侧接口文件,用于向ArkTS暴漏接口。

export const getLedBrightness: (path: string) => number;
export const setLedBrightness: (path: string, brightness: number) => number;

三:Native接口

#include "napi/native_api.h"
#include <hilog/log.h>
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <unistd.h>#define LOG_TAG "NapiLed"
#define LOG_DOMAIN 0x8888  // 自定义领域ID(需在应用配置中注册)static napi_value GetLedBrightness(napi_env env, napi_callback_info info)
{size_t argc = 1;napi_value args[1] = {nullptr};size_t len = 0;napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);napi_status status = napi_get_value_string_utf8(env, args[0], nullptr, 0, &len);if (status != napi_ok) {return nullptr;}char *buff = new char[len+1];std::memset(buff, 0, len+1);napi_get_value_string_utf8(env, args[0], buff, len+1, &len);std::string color = buff;std::string brightnessPath = "/sys/class/leds/" + color + "/brightness";std::ifstream file(brightnessPath);if (!file.is_open()) {delete[] buff;return nullptr;}std::string brightness;std::getline(file, brightness);file.close();napi_value value;napi_create_int32(env, std::stoi(brightness), &value);delete[] buff;return value;
}static int GetLedMaxBrightness(std::string path)
{std::ifstream file(path);int value = 255;  // 默认最大值if (!file.is_open()) {return value;}std::string buffer;if (std::getline(file, buffer)) {try {value = std::stoi(buffer);} catch (...) {std::cerr << "警告: 解析最大亮度值失败,使用默认值255" << std::endl;}} else {std::cerr << "警告: 读取最大亮度值失败,使用默认值255" << std::endl;}file.close();return value;  
}static napi_value SetLedBrightness(napi_env env, napi_callback_info info)
{size_t argc = 2;napi_value args[2] = {nullptr};size_t len = 0;napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);napi_status status = napi_get_value_string_utf8(env, args[0], nullptr, 0, &len);if (status != napi_ok) {return nullptr;}char *buff = new char[len+1];std::memset(buff, 0, len+1);napi_get_value_string_utf8(env, args[0], buff, len+1, &len);std::string color = buff;std::string brightnessPath = "/sys/class/leds/" + color + "/brightness";std::string maxBrightnessPath = "/sys/class/leds/" + color + "/max_brightness";int brightness;int maxBrightness = GetLedMaxBrightness(maxBrightnessPath);napi_get_value_int32(env, args[1], &brightness);if (brightness < 0) brightness = 0;if (brightness > maxBrightness) brightness = maxBrightness;std::ofstream file(brightnessPath);if (!file.is_open()) {OH_LOG_DEBUG(LOG_APP, "open error.");delete[] buff;return nullptr;}file << brightness;file.close();delete[] buff;napi_value value;std::string brightness_str = std::to_string(brightness);napi_create_string_utf8(env, brightness_str.c_str(), brightness_str.length(), &value);return value;}EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports)
{napi_property_descriptor desc[] = {{ "getLedBrightness", nullptr, GetLedBrightness, nullptr, nullptr, nullptr, napi_default, nullptr },{ "setLedBrightness", nullptr, SetLedBrightness, nullptr, nullptr, nullptr, napi_default, nullptr }};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 = "led",.nm_priv = ((void*)0),.reserved = { 0 },
};extern "C" __attribute__((constructor)) void RegisterLedModule(void)
{napi_module_register(&demoModule);
}

四:调试

napi_led.cpp:

# 头文件
#include <hilog/log.h># 定义LOG信息
#define LOG_TAG "NapiLed"
#define LOG_DOMAIN 0x8888  # LOG接口
OH_LOG_DEBUG(LOG_APP, "brightness:%{public}d", brightness);
OH_LOG_INFO(LOG_APP, "brightness:%{public}d", brightness);
OH_LOG_WARN(LOG_APP, "brightness:%{public}d", brightness);
OH_LOG_ERROR(LOG_APP, "brightness:%{public}d", brightness);
OH_LOG_FATAL(LOG_APP, "brightness:%{public}d", brightness);

CMakeLists.txt:链接libhilog_ndk.z.so

target_link_libraries(led PUBLIC libace_napi.z.so libhilog_ndk.z.so)

五:编译

通过构建>编译>编译Hap来生成Native so库。

生成路径:

至此以led为例的NDK开发完成。

http://www.dtcms.com/a/391694.html

相关文章:

  • Dify 从入门到精通(第 87/100 篇):Dify 的多模态模型可观测性(高级篇)
  • 5种获取JavaScript时间戳函数的方法
  • Redis 三种集群模式
  • 初识kotlin协程
  • 多线程——内存可见性问题和指令重排序问题(volatile详解)
  • Linux第十八讲:应用层协议Http
  • 【C++】速识map与set
  • 多层感知机(MLP)
  • Linux系统诊断——拷贝日志系统
  • python中 ​实例方法​(普通方法)和 ​类方法​ 的核心差异
  • Sping AI接入deepseek-本地部署大模型-第二期
  • 数据分析-数据指标体系搭建及应用
  • 计算机专业课《大数据技术》课程导览:开启数据智能时代
  • dumpsys battery 简介
  • 从 CNN 基础到 AlexNet:计算机视觉的破局之路
  • 苏州自动化工厂1台服务器如何5人并发SolidWorks设计
  • 固态硬盘数据恢复一般多少钱?费用分析+恢复教程
  • WebRTC 探秘:构建你自己的实时视频应用
  • 在Ubuntu中离线安装miniconda3
  • Mem0 + 百度智能云向量数据库:为AI打造持久化记忆
  • MySQL 数据归档的技术困境与 Databend 解决之道
  • 2025icpc网络赛第一场The 2025 ICPC Asia East Continent Online Contest (I)
  • docker中ngnix的路径配置
  • 什么是黑板架构风格?
  • Redis 三大核心模式(主从复制 / 哨兵 / 集群):完整部署与问题解析
  • Docker生产环境容器OOM问题定位:镜像内存泄漏还是主机资源不足?
  • AcWing385. GF和猫咪的玩具——Floyd算法
  • 75、封装paddle ocr v5服务支持昇腾800 900 、800I A2、300I DUO卡推理识别
  • 【一文了解】线程的使用
  • 电力系统暂态稳定计算与单机无穷大系统建模