鸿蒙是多编程语言生态。为满足不同业务场景诉求及不同开发者编程习惯,鸿蒙向应用开发者提供ArkTS等多语言混合开发能力,其中ArkTS、仓颉和C/C++是主要编程语言。
ArkTS是动态类型编程语言,主打易学易用、生态丰富、极简开发、持续创新四大特征;仓颉是静态类型编程语言,主打高性能、强安全、跨平台、智能化等特性。C/C++代码可通过跨语言互操作封装为ArkTS、仓颉扩展模块,提供给ArkTS、仓颉高效使用。ArkTS和仓颉均通过垃圾回收机制自动管理内存,C/C++需开发者手动管理内存。
开发者可以根据业务场景需要,选择使用ArkTS、仓颉和C/C++进行特性开发。对于动态更新业务场景、与TS/JS高效互通场景、快速构建等场景建议优先选择ArkTS;对于高吞吐量/高频读写的数据处理场景、高频交互高负载场景、启动时延敏感等场景建议优先选择仓颉;对于游戏引擎、物理仿真等计算密集型任务场景、需要深度优化CPU指令集的专用算法库硬件加速等场景建议优先选择C/C++。
ArkTS、仓颉和C/C++支持高性能互操作,相互配合、互不替代、长期演进、形成优势互补,共同支撑鸿蒙应用生态构建。
鸿蒙APP架构示意图

ArkTS是鸿蒙首选应用开发高级语言。
ArkTS基于TypeScript(简称TS),保持了TS的基本语法和风格,同时通过引入类型校验模式和类型推断增强规则,强化开发期静态检查和分析能力,提升代码健壮性,并实现更好的程序执行稳定性和性能。ArkTS同时也支持与TS/JavaScript(简称JS)高效互操作以复用业界TS/JS生态技术资产。ArkTS已广泛应用于鸿蒙应用生态。
在标准TS的基础上,ArkTS结合鸿蒙应用开发的诉求进行了创新和能力扩展,主要新增四大特性如下:
ArkTS在保持TS基本语法风格的基础上,引入以下规则,强化开发期代码静态检查和分析能力,提升代码健壮性并实现更好的程序执行性能:
方舟编译运行时(ArkCompiler)支持ArkTS、TS、JS的编译运行,目前它主要分为ArkTS编译工具链和ArkTS运行时两部分。其中ArkTS编译工具链负责在开发侧将高级语言编译为方舟字节码文件(*.abc),而ArkTS运行时则负责在设备侧运行字节码文件执行程序逻辑。
ArkTS会结合鸿蒙应用开发的需求持续创新,平滑演进。进一步丰富并发编程、完善类型系统、现代化语法等显著改进和新特性,使开发者能够更快速地构建稳定且性能优越的应用。
仓颉也是鸿蒙应用开发高级语言。
仓颉是一款静态类型、静态编译的编程语言,通过现代语言特性的集成、全方位的编译优化和运行时实现、以及开箱即用的工具链支持,为鸿蒙应用开发者打造友好开发体验和卓越程序性能。
同时,仓颉的全部模块包括编译器、语言运行时、标准库及工具链等均已开源并实现社区化开发和运作,欢迎参与仓颉开源社区贡献,参见链接:仓颉开源社区。OpenHarmony社区版本默认继承仓颉语言社区版本。
仓颉的具体特性表现为:
鸿蒙应用开发全面支持C/C++语言开发能力,为开发者提供开发套件(NDK)及配套工具链。基于C/C++实现的功能模块,可通过跨语言互操作封装为ArkTS、仓颉扩展模块,提供给ArkTS、仓颉高效使用。
在鸿蒙应用开发中,ArkTS 凭借其声明式 UI、丰富的组件库和高效的开发工具链,能够显著提升开发效率,让开发者快速构建跨设备应用。相比之下,C API开发门槛高、需要手动管理内存、调试复杂,开发效率较低。因此,当前鸿蒙的开放策略明确以 ArkTS 优先,C API则遵循谨慎提供原则——仅针对高性能计算、底层系统交互、游戏渲染等对实时性或算力要求极高的场景进行开放,确保在保持高效开发体验的同时,为关键性能诉求提供必要的底层能力支撑,当前如下场景会提供C API:
为构建符合鸿蒙技术标准的应用开发能力,提供了一套完整的C/C++开发组件体系,具体包括:
开发者可以使用Node-API实现ArkTS和C/C++的跨语言交互。ArkTS提供的Node-API是基于Node.js 18.x LTS的Node-API规范扩展开发的机制,为开发者提供了ArkTS与C/C++模块之间的交互能力。它提供了一组稳定的、跨平台的API,可以在不同的操作系统上使用。
使用ArkTS语言开发鸿蒙应用一般情况下无需依赖C/C++库,但部分场景由于性能、效率等要求,比如游戏引擎、物理仿真等,需要依赖使用C/C++库。Node-API规范封装了I/O、CPU密集型、OS底层等能力并对外暴露ArkTS接口,从而实现ArkTS和C/C++的交互。
涉及到互操作的主要场景如下:
Node-API的组成架构

Node-API的关键交互流程

ArkTS和C++之间的交互流程,主要分为以下两步:
仓颉支持与 C 互操作,即支持仓颉函数与 C 语言函数的互相调用以及跨语言数据转换。对于 C++ 代码,开发者首先需要把 C++ 接口封装成 C 接口,再由仓颉通过互操作调用。
仓颉与 C 互操作机制考虑兼顾互操作语法的简洁性,以及低互操作开销,主要提供以下能力:
以下案例演示了一个使用仓颉与C互操作的典型场景,在C侧产生一段较大的文本,需要传递到仓颉侧作为 String 处理。借助仓颉与C互操作特性,整个过程可以做到“零拷贝”。
仓颉侧代码:
// 声明 C 函数 // 对于逻辑简单函数调用,使用@FastNative注解指示编译器采用更轻量的调用约定,减少运行时开销 @FastNative foreign func getTextSize(): Int32 foreign func fillLargeText(buf: CPointer<UInt8>, maxLen: Int32): Int32 func handleText() { // 1. 先从 C 侧获取目标文本的精确字节长度 let textSize = Int64(getTextSize()) println("C 侧文本大小: ${textSize} 字节") // 2. 在仓颉侧创建精确大小的 Array<UInt8> var buffer = Array<UInt8>(textSize, repeat: 0) unsafe { // 3. 获取数组原始指针 let handle: CPointerHandle<UInt8> = acquireArrayRawData(buffer) // 4. 将指针传入 C 侧,C 侧直接往仓颉数组内存中写入 UTF-8 数据 let actualLen = fillLargeText(handle.pointer, Int32(textSize)) // 5. 写完后立即释放原始指针 releaseArrayRawData(handle) // 6. 免拷贝构造 String(buffer 的所有权转移给 String,后续不应再修改) let text: String = String.withRawData(buffer) println("实际接收字节数: ${actualLen}") println("字符串内容: ${text}") } }
C侧代码:
#include <string.h> #include <stdint.h> #define MAX_LENGTH 1024 // 返回文本的字节长度 int32_t getTextSize() { return MAX_LENGTH; } // 向 buf 指向的内存写入 UTF-8 文本,最多写入 maxLen 字节 // 返回实际写入的字节数 int32_t fillLargeText(uint8_t* buf, int32_t maxLen) { int32_t len = 256; if (len > maxLen) { len = maxLen; } // 需要在此处填写实际的写入 buf 的代码逻辑 return len; }
上述代码在使用中需要注意以下事项:
更详细描述请参考《仓颉编程语言开发指南》中 仓颉-C 互操作 章节。
鸿蒙支持ArkTS 和仓颉混合开发,针对互操作场景诉求,仓颉提供 ohos.ark_interop 互操作库来实现与 ArkTS 的互操作。该库主要提供以下关键数据结构:
关于仓颉-ArkTS互操作更详细的使用,例如类型转换、高性能string编码、对象生命周期管理、约束和限制等, 请参考《仓颉编程语言开发指南》中 仓颉-ArkTS 互操作 章节。
ArkTS 调用仓颉
在使用 ArkTS 开发时,通过跨语言互操作调用仓颉开发的代码模块,发挥仓颉高性能高并发优势,提升应用性能体验。针对这一场景诉求,可使用互操作库,在仓颉侧实现可被互操作调用的接口,示例如下:
package ohos_app_cangjie_entry // 导入互操作库 import ohos.ark_interop.* func addNumber(context: JSContext, callInfo: JSCallInfo): JSValue { // 从JSCallInfo获取参数列表 let arg0: JSValue = callInfo[0] let arg1: JSValue = callInfo[1] // 把JSValue转换为仓颉类型 let a: Float64 = arg0.toNumber() let b: Float64 = arg1.toNumber() // 实际仓颉函数行为 let value = a + b // 把结果转换为JSValue let result: JSValue = context.number(value).toJSValue() // 返回 JSValue return result } // 必须注册该函数到JSModule中 let EXPORT_MODULE = JSModule.registerModule { runtime, exports => exports["addNumber"] = runtime.function(addNumber).toJSValue() }
然后在 ArkTS 侧加载仓颉模块,并调用该接口
// 导入仓颉动态库,该动态库名称为仓颉包名的名称,该名称需要和互操作接口所在的包名一致 import { addNumber } from "libohos_app_cangjie_entry.so"; // 调用仓颉接口 let result = addNumber(1, 2);
同时为了提升开发者易用性,仓颉提供声明式互操作宏机制,使开发者可以标注仓颉代码中需要被 ArkTS 跨语言使用的函数或类型,在编译阶段自动生成互操作“胶水层”代码及 ArkTS 接口声明,从而减少开发者手写互操作代码的复杂度。比如以上案例中仓颉侧代码可以简化成:
import ohos.ark_interop.* import ohos.ark_interop_macro.* @Interop[ArkTS] public func addNumber(a: Float64, b: Float64): Float64 { a + b }
仓颉调用 ArkTS
在使用仓颉开发时,通过跨语言互操作调用 ArkTS 库,复用 ArkTS 丰富的生态。针对这一场景诉求,可使用互操作库,加载 ArkTS 系统(包括NAPI模块和ABC模块)并调用相应接口
加载并调用NAPI模块示例如下:
package ohos_app_cangjie_entry import ohos.ark_interop.* func callInterop(context: JSContext) { // 加载ArkTS系统NAPI模块 , 参数是对应的系统模块名 let sysMod: JSObject = context.requireArkModule("@ohos.usbManager").asObject() // 加载ArkTS应用NAPI模块 , 参数是对应的模块路径 let appMod: JSObject = context.requireArkModule("libentry.so").asObject() // 获取ArkTS系统NAPI模块导出函数 let getDevices = sysMod["getDevices"].asFunction() // 调用ArkTS系统NAPI模块函数 getDevices.call() // 获取ArkTS应用NAPI模块导出函数 let getTest = appMod["Test"].asFunction() // 调用ArkTS应用NAPI函数 getTest.call() }
加载并调用ABC模块示例如下:
package ohos_app_cangjie_entry import ohos.ark_interop.* func loadModule(context: JSContext): Unit { // 1. 使用requireArkModule导入ABC模块 , 参数是对应的模块路径 let module = context.requireArkModule("entry/src/main/ets/Test") // 2. 把导入内容转换为JSObject let test = module.asObject() // 3. 读取导出的value变量 let value = test["value"].toNumber() // 4. 写value变量 test["value"] = context.number(2).toJSValue() // 5. 调用导出的test方法 test.callMethod("test") }
为了提升该场景开发者易用性,DevEco Studio 提供工具对 ArkTS 库进行互操作自动封装。当开发者在仓颉工程中导入 ArkTS 库时,该工具解析 ArkTS 库的接口声明文件(.d.ts或者.d.ets文件),生成仓颉调用 ArkTS 接口的互操作“胶水层”代码,开发者直接调用由工具生成的仓颉接口即可,从而避免开发者手写互操作代码的复杂度。
ArkTS、仓颉和C/C++是鸿蒙的主要编程语言,三种语言相互配合,共同支撑鸿蒙应用生态构建。鸿蒙同时也支持开发者使用JavaScript、TypeScript、Dart、Kotlin等编程语言基于React Native(RN)、Flutter、Kotlin Multiplatform + Compose Multiplatform(KMP+CMP)等主流跨平台框架进行应用开发。当前Python、Go、Rust、Java、Julia等语言社区也在积极支持鸿蒙发展,开发者也可以使用这些编程语言在鸿蒙上开发
编程语言 | 使用方式 |
|---|---|
Dart | 使用Flutter框架,开发跨平台应用 |
JavaScript TypeScript | 使用React Native、Electron等框架,开发跨平台应用 |
Kotlin | 使用KMP+CMP框架,开发跨平台应用 |
Python | 社区提供语言运行时,具体可参见OpenHarmonyPCDeveloper开源社区 |
Go | 同上 |
Rust | 同上 |
Java | 同上 |
Julia | 同上 |