想在一个已经跑通的 Rust 项目里复用性能敏感的加密、编解码或数据处理逻辑,搬到开源鸿蒙上,却发现官方主推的路线自始至终是 ArkTS——这不是个别工程师的错觉,而是当前鸿蒙原生开发的基本形态。ohos-rs 正是在这个缝隙里出现的项目:它不打算取代 ArkTS,而是把 Rust 编译成鸿蒙能加载的原生模块,让 ArkTS 侧像调用普通模块一样调用它。值不值得为此改造工具链,取决于你要解决的是哪一类问题。

ohos-rs 到底解决哪一层问题
官方为 OpenHarmony 应用开发者提供的 SDK 面向 ArkTS,系统能力通过 ArkTS 接口暴露。如果你的需求落在 UI、页面路由、状态管理这一层,ArkTS 完全够用,没必要引入第二套语言。真正卡住人的是另一种场景:已有 Rust 实现(比如密码学、压缩、序列化、图像处理),或者某段算法用 ArkTS 写性能不达标,需要下沉到原生层。
按官方文档的描述,ohos-rs 基于 napi-rs 改造,沿用其 Rust-first 的绑定方式,把 Rust 代码编译成符合 Node-API 风格的原生模块,由 ArkTS 侧导入调用(来源:ohos-rs Docs)。换句话说,它填的是"原生模块"这一层,而不是应用框架层。理解了这一点,后面的选型判断就顺了:它适合做计算密集型、可复用、边界清晰的模块,不适合拿来重写整个页面逻辑。
核心机制值得多说两句。napi-rs 的思路是用 Rust 宏(如 #[napi])标注导出函数与类型,由宏完成 Rust 类型与 JS/ArkTS 值之间的转换代码生成,编译结果是 .so 动态库。跨线程回调是这类绑定最容易踩坑的地方:Rust 侧的工作线程要把结果送回上层,需要 ThreadSafeFunction(简称 TSFN),ohos-rs 文档里有专门一节讲它的定义与使用时机(来源:ThreadSafeFunction)。如果你的模块只是纯函数、同步返回,可以暂时不碰它;一旦涉及异步任务、回调、事件推送,TSFN 就是绕不开的基础设施。
生态现状:能用,但别指望开箱即用
判断一个绑定层项目是否值得投入,先看它周围有没有现成轮子。ohos-rs 的生态页列出了几类内容(来源:ohos-rs Ecosystem):
- @ohos-rs 包:crc32、jieba、argon2、bcrypt、jsonwebtoken、snappy、xxhash、image 等,基本是把常见 Rust crate 包装成鸿蒙可用的模块。
- 原生绑定:hilog(日志)、init 等系统能力的 Rust 侧封装。
- Polyfill:AbortController、WebStreams 这类前端运行时缺失的 API 补齐。
- 第三方库:OpenSSL、cURL、MMKV、avif、cronet 等较重量级的依赖移植。
这个清单说明项目已经过了"只能跑 Hello World"的阶段,但也暴露了边界:包的数量有限,覆盖的是通用基础能力,业务侧的具体需求大概率还是要自己写绑定。如果你期待的是"npm 上有的鸿蒙上基本都有",目前还差得远。
版本配套同样需要留意。以 OpenHarmony 6.0 Release 为例,其 Public SDK 为 Ohos_sdk_public 6.0.0.47(API Version 20 Release),DevEco Studio 侧对应 6.0.0 Release(来源:OpenHarmony 6.0 Release Notes)。这类版本号不是装饰,SDK 的 API 版本、NDK 的 sysroot、ohos-rs 自身支持的 API 范围三者要能对上,否则很容易出现编译通过、运行期符号找不到的情况。开工前先确认这三者,比事后排查省事得多。
环境准备:真正花时间的地方
Rust 侧的准备工作本身不复杂,麻烦的是让它认识鸿蒙的交叉编译目标。整体可以拆成四步。
第一步,装 Rust 工具链并添加 OHOS 目标。 目标三元组是 aarch64-unknown-linux-ohos,真机基本都用这个;如果要跑 x86-64 主机上的模拟器,则用 x86_64-unknown-linux-ohos。Servo 项目的 OpenHarmony 构建文档里也直接用了这两个 target 名(来源:The Servo Book),可以作为交叉编译目标的旁证。
rustup target add aarch64-unknown-linux-ohos
rustup target add x86_64-unknown-linux-ohos
第二步,准备 OpenHarmony SDK / NDK。 你需要其中的 native 部分:链接器和 sysroot。官方 SDK 体积不小,社区维护了镜像仓库方便下载(来源:openharmony-rs/ohos-sdk Releases)。
第三步,告诉 Cargo 用哪个链接器、去哪里找 sysroot。 这一步最容易出错。下面是一份结构示意,路径必须换成你本机的实际安装位置:
[target.aarch64-unknown-linux-ohos]
linker = "/path/to/ohos-sdk/native/llvm/bin/clang"
rustflags = ["-Clink-arg=--sysroot=/path/to/ohos-sdk/native/sysroot"]
第四步,处理依赖下载。 如果 crates.io 访问不畅,在 .cargo/config.toml 里配镜像源是常规操作,不影响项目本身。
在 Windows 上还有一层额外注意:有移植笔记提到,rustc 在 Windows 上是直接调用链接器的,不会去解析 .cmd / .bat 包装脚本,所以链接器路径要直接指到 clang.exe 而不是某个批处理入口(来源:Tauri 应用移植到 OpenHarmony 笔记)。这类细节在文档里不显眼,但卡住的时候会很费时间。
最小示例:从函数到 .so
环境通了之后,先别急着上真实业务,用一个函数跑通全链路。用宏标注一个导出函数,例如一个接收两个整数返回和的 add,编译后应得到 lib<name>.so。构建命令就是标准的 cargo 交叉编译:
cargo build --target aarch64-unknown-linux-ohos --release
产物落在 target/aarch64-unknown-linux-ohos/release/ 下。构建成功不等于能用,建议做两层验证。

静态验证:用 file 确认它是 ARM aarch64 的共享对象,用 readelf -d 或 nm 看看导出的符号和依赖动态库是否齐全。这一步能提前发现架构错配、依赖库缺失这类问题,比把错误带到设备上再查要快。
动态验证:把它放进鸿蒙工程,在 ArkTS 侧按原生模块的导入方式引入并调用,观察实际返回值。只有这一步通过了,才说明绑定层、SDK 版本、运行时加载三者真的对齐。
顺带一提日志:调试阶段用 hilog 的 Rust 绑定比 println! 靠谱,因为原生层的标准输出在设备上不一定能被你看到。
限制与排错:哪些坑是结构性的
把这套流程跑一遍之后,就能比较客观地评估它了。下面几类问题不是"配置没对",而是方案本身的边界。
它不是 ArkTS 的通用替代。 官方工具链、文档、示例、生态都以 ArkTS 为中心,ohos-rs 补的是原生模块这一块。你要付出的成本包括维护交叉编译配置、管理 SDK 版本对齐、自己写绑定代码。如果需求能用 ArkTS 表达,用 ArkTS 就是更省事的选择。
生态成熟度仍处于早期。 现成包覆盖基础能力,业务逻辑基本要自己动手。第三方库移植(OpenSSL、cURL 这类)虽然已有先例,但每个大依赖都可能带来额外的链接和 sysroot 配置工作。
版本与 API 对齐是持续成本。 SDK 升级、API 版本变化、ohos-rs 支持范围变动,三者任意一个动都可能需要重新验证。这不是一次性配置好就一劳永逸的事。
跨线程回调要专门设计。 涉及异步任务时,TSFN 的使用方式会直接影响模块的结构;如果一开始没考虑清楚,后期改动量不小。
链接与构建脚本问题最集中。 找不到 -lc、sysroot 路径不对、build.rs 里写了针对桌面平台的判断逻辑,都是常见报错来源。排查顺序建议是:先确认 target 装没装,再看 linker 与 sysroot 路径,然后看 build.rs 和依赖的 links 配置,最后才怀疑代码本身。
判断是否值得投入
一个比较务实的判断标准是:你手上有没有一段"确实需要 Rust"的代码。如果有现成的 Rust 实现需要在鸿蒙上复用,或者某个模块的性能瓶颈已经明确,ohos-rs 是目前少有的可行路径,值得投入时间把工具链跑通。反过来,如果只是"想试试 Rust 写鸿蒙应用",那大概率会在链接配置和生态缺口上消耗掉热情,收益不成正比。
把它定位成探索性方案更准确:能用、能落地、有真实项目在跑,但还不是通用推荐。先做一个纯函数级别的最小验证,确认构建、加载、调用三步都通,再决定要不要把更大范围的逻辑迁过来——这个顺序能让你在投入变大之前,先看清它在你具体场景里的真实上限。

评论列表 (1条):
加载更多评论 Loading...