在鸿蒙HarmonyOS生态中NDKNative Development Kit是官方提供的一套 Native API、编译脚本及工具链集合旨在帮助开发者使用 C/C 语言实现应用的关键功能。一、 NDK 的核心能力与适用场景NDK 并非要替代 ArkTS而是作为其性能补充方案。它覆盖了鸿蒙的一些基础底层能力主要包括跨语言交互提供 Node-API曾用名 NAPI实现 ArkTS/JS 与 C/C 之间的无缝调用。基础与图形库支持标准 C/C 库、OpenGL3D图形、Drawing2D图形、OpenSL ES音频加速。系统与IO提供 FFRT并发编程框架、libuv异步IO、Rawfile应用资源访问、HiLog日志等。推荐使用 NDK 的场景性能敏感游戏引擎、物理模拟、音视频处理等计算密集型任务。代码复用需要集成成熟的第三方 C/C 库如 OpenCV、FFmpeg。硬件优化需要针对特定 CPU 特性如 ARM Neon 指令集进行专项定制。不建议使用的场景纯 C/C 应用开发或对跨设备兼容性要求极高的简单业务逻辑这类场景使用 ArkTS 效率更高。1. 跨语言交互Node-API 实现 ArkTS 与 C 双向调用Node-API 是 ArkTS 与 C 之间的桥梁。以下示例展示了如何在 C 侧实现一个加法函数并安全地解析 ArkTS 传入的参数。C 侧实现 (native-lib.cpp)#include napi/native_api.h // C 侧的加法函数实现 static napi_value Add(napi_env env, napi_callback_info info) { size_t argc 2; napi_value args[2]; // 获取回调信息 napi_get_cb_info(env, info, argc, args, nullptr, nullptr); // 解析 ArkTS 传入的 double 参数 double value1, value2; napi_get_value_double(env, args[0], value1); napi_get_value_double(env, args[1], value2); // 计算结果并返回给 ArkTS napi_value result; napi_create_double(env, value1 value2, result); return result; } // 模块初始化与接口导出 static napi_value Init(napi_env env, napi_value exports) { napi_property_descriptor desc[] { {add, nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr} }; napi_define_properties(env, exports, sizeof(desc)/sizeof(desc[0]), desc); return exports; } // 模块注册 static napi_module demoModule { .nm_version 1, .nm_flags 0, .nm_modname nativeLib, .nm_register_func Init, }; extern C __attribute__((constructor)) void RegisterModule() { napi_module_register(demoModule); }ArkTS 侧调用 (Index.ets)import nativeLib from libnativeLib.so; Entry Component struct NativeDemo { State result: number 0; build() { Button(调用Native加法) .onClick(() { this.result nativeLib.add(25, 37); }) } }2. 图形绘制利用 Drawing API 进行 2D 渲染NDK 提供了系统级的 2D 图形库Drawing允许开发者在 Native 层直接操作 Canvas 进行高性能绘制。#include arkui/native_node.h #include drawing/native_drawing_canvas.h // 在自定义绘制事件回调中获取 Canvas 并绘制 void OnCustomEvent(ArkUI_NodeCustomEvent *event) { auto drawContext OH_ArkUI_NodeCustomEvent_GetDrawContextInDraw(event); auto canvas reinterpret_castOH_Drawing_Canvas *( OH_ArkUI_DrawContext_GetCanvas(drawContext)); // 在 Native 层直接绘制矩形 OH_Drawing_CanvasDrawRect(canvas, 10, 10, 100, 100); }3. 硬件优化ARM Neon 指令集加速图像处理对于性能敏感的场景如实时滤镜NDK 允许开发者直接调用底层 CPU 特性进行 SIMD 并行计算大幅降低耗时。#include arm_neon.h // 使用 Neon 指令集加速的图像锐化滤镜 void neon_sharpen(uint8_t* data, int width, int height) { const int stride width * 4; for (int y 1; y height - 1; y) { for (int x 1; x width - 1; x 8) { // 批量加载像素块利用 Neon 寄存器 uint8x8x4_t mid vld4_u8(data y*stride x*4); // ... 执行向量化锐化计算并写回内存 } } }4. 系统与IO使用 HiLog 输出原生层日志在 C 层进行逻辑调试时可以直接调用系统的 HiLog 接口将日志无缝输出到 DevEco Studio 的日志面板中。#include hilog/log.h #undef LOG_DOMAIN #undef LOG_TAG #define LOG_DOMAIN 0xFF00 #define LOG_TAG NativeModule void SomeNativeFunction() { // 打印 Info 级别日志 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, Native function executed successfully.); }二、 NDK 开发环境准备进行 NDK 开发需要具备以下基础前置知识Linux C 编程知识鸿蒙底层基于 POSIX 标准扩展熟悉 Linux C 编程有助于理解。CMake 构建系统CMake 是鸿蒙默认的构建工具需掌握基础的CMakeLists.txt编写。Node Addons 开发知识了解 Node Addons 模式有助于更好地理解 Node-API 的跨语言调用。Clang/LLVM 编译器具备相关基础知识有助于编译出更优的 Native 动态库。三、 工程架构与开发流程在 DevEco Studio 中创建 Native C 模板后会自动生成标准的 NAPI 工程结构。其核心架构分为三层应用侧ArkTS Native Module开发者使用 Node-API 开发的模块供 ArkTS 侧import引入。NDK 功能模块Framework包含 Node-API 交互逻辑、ModuleManager模块加载与查找、ScopeManager 和 ReferenceManager管理 napi_value 和 napi_ref 的生命周期。运行时ArkTS RuntimeArkCompiler 与方舟运行时底层的 Native Engine 对 JS 引擎做了封装使 NDK 层无需感知 JS 引擎的差异。核心开发流程Native 侧实现在 C 源码如hello.cpp中编写业务逻辑并通过__attribute__((constructor))修饰的方法自动调用napi_module_register()完成模块注册。接口声明在index.d.ts文件中声明对外暴露的 ArkTS 接口并在oh-package.json5中进行关联。CMake 编译通过CMakeLists.txt配置编译参数工具链读取ohos.toolchain.cmake中的默认值将 C 代码编译为动态链接库.so文件。ArkTS 侧调用ArkTS 引入编译好的.so文件即可像调用普通 JS 模块一样调用 C 侧的函数。四、 极致并发TaskPool 与 Native 的深度结合在鸿蒙中ArkTS 侧可以通过taskpool实现多线程并发而 NDK 同样支持这一机制。将 C 层的耗时计算下沉到 TaskPool 中是避免阻塞 UI 线程的最佳实践。实战场景在 ArkTS 侧定义带有Concurrent装饰器的函数并在其中调用 Native 模块如testNapi.store()。核心机制当 Native 对象跨线程传递时需要利用napi_coerce_to_native_binding_object接口绑定detach和attach回调。在序列化当前线程阶段执行 detach在反序列化目标线程阶段执行 attach从而安全地将 Native 对象传递给 TaskPool 工作线程。五、 纯 Native 渲染NDK UI API 架构对于极度追求渲染性能的场景如自定义复杂动画、游戏引擎渲染鸿蒙提供了 NDK UI API允许开发者完全在 C 侧构建和管理 UI 节点。节点创建与挂载通过OH_ArkUI_NodeContent_AddNode接口可以将 Native 侧创建的组件节点挂载到 ArkTS 的NodeContent对象上。组件属性控制利用createNode创建特定类型的节点如ARKUI_NODE_LIST、ARKUI_NODE_TEXT并通过setAttribute动态设置组件属性如滚动条状态、对齐方式等实现纯 C 驱动的界面渲染。六、 跨设备互通Service Collaboration Kit在分布式场景下NDK 提供了强大的跨设备协同能力允许 TV、Tablet 或 PC 等本端设备直接调用远端 Phone 的硬件能力。接口调用通过HMS_ServiceCollaboration_GetCollaborationDeviceInfos获取可用设备列表使用HMS_ServiceCollaboration_StartCollaboration拉起远端设备的相机TAKE_PHOTO、扫描SCAN_DOCUMENT或图库IMAGE_PICKER能力。数据回传构建ServiceCollaborationCallback通过事件回调OnEventProc和数据回调OnDataCallbackProc实时接收对端回传的图片或视频流数据。七、 进阶内存与事件循环管理随着鸿蒙系统的不断迭代NDK 提供了更精细的内存与事件管理机制强引用与字符串优化在最新的 SDK 中支持使用扩展的 Node-API 接口创建对 ArkTS 对象的强引用防止其在跨语言传递时被意外 GC。同时提供external string机制允许 ArkTS 侧直接读取 C 层中的字符串避免额外的内存拷贝。Native 事件循环对于需要在后台独立运行的 Native 服务可使用napi_run_event_loop和napi_stop_event_loop在异步线程中触发和停止底层事件循环实现复杂的异步任务调度。八、 前沿特性跟进API 26 / HarmonyOS 7紧跟鸿蒙生态的演进NDK 开发也在不断吸收最新的底层能力图形加速Graphics Accelerate Kit 新增了预启动特性结合 NDK 的 NativeBuffer 跨进程共享能力可大幅提升游戏和重型应用的启动体验。多媒体增强音频 NDK 新增了投播接口和系统级桌面歌词功能Canvas 模块的 Drawing NDK 也补齐了 Path、Matrix 等高级图形操作为 Native 侧的自定义绘制提供了更完善的底层支持。
NDK开发:在鸿蒙中使用Native API(51)
在鸿蒙HarmonyOS生态中NDKNative Development Kit是官方提供的一套 Native API、编译脚本及工具链集合旨在帮助开发者使用 C/C 语言实现应用的关键功能。一、 NDK 的核心能力与适用场景NDK 并非要替代 ArkTS而是作为其性能补充方案。它覆盖了鸿蒙的一些基础底层能力主要包括跨语言交互提供 Node-API曾用名 NAPI实现 ArkTS/JS 与 C/C 之间的无缝调用。基础与图形库支持标准 C/C 库、OpenGL3D图形、Drawing2D图形、OpenSL ES音频加速。系统与IO提供 FFRT并发编程框架、libuv异步IO、Rawfile应用资源访问、HiLog日志等。推荐使用 NDK 的场景性能敏感游戏引擎、物理模拟、音视频处理等计算密集型任务。代码复用需要集成成熟的第三方 C/C 库如 OpenCV、FFmpeg。硬件优化需要针对特定 CPU 特性如 ARM Neon 指令集进行专项定制。不建议使用的场景纯 C/C 应用开发或对跨设备兼容性要求极高的简单业务逻辑这类场景使用 ArkTS 效率更高。1. 跨语言交互Node-API 实现 ArkTS 与 C 双向调用Node-API 是 ArkTS 与 C 之间的桥梁。以下示例展示了如何在 C 侧实现一个加法函数并安全地解析 ArkTS 传入的参数。C 侧实现 (native-lib.cpp)#include napi/native_api.h // C 侧的加法函数实现 static napi_value Add(napi_env env, napi_callback_info info) { size_t argc 2; napi_value args[2]; // 获取回调信息 napi_get_cb_info(env, info, argc, args, nullptr, nullptr); // 解析 ArkTS 传入的 double 参数 double value1, value2; napi_get_value_double(env, args[0], value1); napi_get_value_double(env, args[1], value2); // 计算结果并返回给 ArkTS napi_value result; napi_create_double(env, value1 value2, result); return result; } // 模块初始化与接口导出 static napi_value Init(napi_env env, napi_value exports) { napi_property_descriptor desc[] { {add, nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr} }; napi_define_properties(env, exports, sizeof(desc)/sizeof(desc[0]), desc); return exports; } // 模块注册 static napi_module demoModule { .nm_version 1, .nm_flags 0, .nm_modname nativeLib, .nm_register_func Init, }; extern C __attribute__((constructor)) void RegisterModule() { napi_module_register(demoModule); }ArkTS 侧调用 (Index.ets)import nativeLib from libnativeLib.so; Entry Component struct NativeDemo { State result: number 0; build() { Button(调用Native加法) .onClick(() { this.result nativeLib.add(25, 37); }) } }2. 图形绘制利用 Drawing API 进行 2D 渲染NDK 提供了系统级的 2D 图形库Drawing允许开发者在 Native 层直接操作 Canvas 进行高性能绘制。#include arkui/native_node.h #include drawing/native_drawing_canvas.h // 在自定义绘制事件回调中获取 Canvas 并绘制 void OnCustomEvent(ArkUI_NodeCustomEvent *event) { auto drawContext OH_ArkUI_NodeCustomEvent_GetDrawContextInDraw(event); auto canvas reinterpret_castOH_Drawing_Canvas *( OH_ArkUI_DrawContext_GetCanvas(drawContext)); // 在 Native 层直接绘制矩形 OH_Drawing_CanvasDrawRect(canvas, 10, 10, 100, 100); }3. 硬件优化ARM Neon 指令集加速图像处理对于性能敏感的场景如实时滤镜NDK 允许开发者直接调用底层 CPU 特性进行 SIMD 并行计算大幅降低耗时。#include arm_neon.h // 使用 Neon 指令集加速的图像锐化滤镜 void neon_sharpen(uint8_t* data, int width, int height) { const int stride width * 4; for (int y 1; y height - 1; y) { for (int x 1; x width - 1; x 8) { // 批量加载像素块利用 Neon 寄存器 uint8x8x4_t mid vld4_u8(data y*stride x*4); // ... 执行向量化锐化计算并写回内存 } } }4. 系统与IO使用 HiLog 输出原生层日志在 C 层进行逻辑调试时可以直接调用系统的 HiLog 接口将日志无缝输出到 DevEco Studio 的日志面板中。#include hilog/log.h #undef LOG_DOMAIN #undef LOG_TAG #define LOG_DOMAIN 0xFF00 #define LOG_TAG NativeModule void SomeNativeFunction() { // 打印 Info 级别日志 OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, Native function executed successfully.); }二、 NDK 开发环境准备进行 NDK 开发需要具备以下基础前置知识Linux C 编程知识鸿蒙底层基于 POSIX 标准扩展熟悉 Linux C 编程有助于理解。CMake 构建系统CMake 是鸿蒙默认的构建工具需掌握基础的CMakeLists.txt编写。Node Addons 开发知识了解 Node Addons 模式有助于更好地理解 Node-API 的跨语言调用。Clang/LLVM 编译器具备相关基础知识有助于编译出更优的 Native 动态库。三、 工程架构与开发流程在 DevEco Studio 中创建 Native C 模板后会自动生成标准的 NAPI 工程结构。其核心架构分为三层应用侧ArkTS Native Module开发者使用 Node-API 开发的模块供 ArkTS 侧import引入。NDK 功能模块Framework包含 Node-API 交互逻辑、ModuleManager模块加载与查找、ScopeManager 和 ReferenceManager管理 napi_value 和 napi_ref 的生命周期。运行时ArkTS RuntimeArkCompiler 与方舟运行时底层的 Native Engine 对 JS 引擎做了封装使 NDK 层无需感知 JS 引擎的差异。核心开发流程Native 侧实现在 C 源码如hello.cpp中编写业务逻辑并通过__attribute__((constructor))修饰的方法自动调用napi_module_register()完成模块注册。接口声明在index.d.ts文件中声明对外暴露的 ArkTS 接口并在oh-package.json5中进行关联。CMake 编译通过CMakeLists.txt配置编译参数工具链读取ohos.toolchain.cmake中的默认值将 C 代码编译为动态链接库.so文件。ArkTS 侧调用ArkTS 引入编译好的.so文件即可像调用普通 JS 模块一样调用 C 侧的函数。四、 极致并发TaskPool 与 Native 的深度结合在鸿蒙中ArkTS 侧可以通过taskpool实现多线程并发而 NDK 同样支持这一机制。将 C 层的耗时计算下沉到 TaskPool 中是避免阻塞 UI 线程的最佳实践。实战场景在 ArkTS 侧定义带有Concurrent装饰器的函数并在其中调用 Native 模块如testNapi.store()。核心机制当 Native 对象跨线程传递时需要利用napi_coerce_to_native_binding_object接口绑定detach和attach回调。在序列化当前线程阶段执行 detach在反序列化目标线程阶段执行 attach从而安全地将 Native 对象传递给 TaskPool 工作线程。五、 纯 Native 渲染NDK UI API 架构对于极度追求渲染性能的场景如自定义复杂动画、游戏引擎渲染鸿蒙提供了 NDK UI API允许开发者完全在 C 侧构建和管理 UI 节点。节点创建与挂载通过OH_ArkUI_NodeContent_AddNode接口可以将 Native 侧创建的组件节点挂载到 ArkTS 的NodeContent对象上。组件属性控制利用createNode创建特定类型的节点如ARKUI_NODE_LIST、ARKUI_NODE_TEXT并通过setAttribute动态设置组件属性如滚动条状态、对齐方式等实现纯 C 驱动的界面渲染。六、 跨设备互通Service Collaboration Kit在分布式场景下NDK 提供了强大的跨设备协同能力允许 TV、Tablet 或 PC 等本端设备直接调用远端 Phone 的硬件能力。接口调用通过HMS_ServiceCollaboration_GetCollaborationDeviceInfos获取可用设备列表使用HMS_ServiceCollaboration_StartCollaboration拉起远端设备的相机TAKE_PHOTO、扫描SCAN_DOCUMENT或图库IMAGE_PICKER能力。数据回传构建ServiceCollaborationCallback通过事件回调OnEventProc和数据回调OnDataCallbackProc实时接收对端回传的图片或视频流数据。七、 进阶内存与事件循环管理随着鸿蒙系统的不断迭代NDK 提供了更精细的内存与事件管理机制强引用与字符串优化在最新的 SDK 中支持使用扩展的 Node-API 接口创建对 ArkTS 对象的强引用防止其在跨语言传递时被意外 GC。同时提供external string机制允许 ArkTS 侧直接读取 C 层中的字符串避免额外的内存拷贝。Native 事件循环对于需要在后台独立运行的 Native 服务可使用napi_run_event_loop和napi_stop_event_loop在异步线程中触发和停止底层事件循环实现复杂的异步任务调度。八、 前沿特性跟进API 26 / HarmonyOS 7紧跟鸿蒙生态的演进NDK 开发也在不断吸收最新的底层能力图形加速Graphics Accelerate Kit 新增了预启动特性结合 NDK 的 NativeBuffer 跨进程共享能力可大幅提升游戏和重型应用的启动体验。多媒体增强音频 NDK 新增了投播接口和系统级桌面歌词功能Canvas 模块的 Drawing NDK 也补齐了 Path、Matrix 等高级图形操作为 Native 侧的自定义绘制提供了更完善的底层支持。