Rust在移动开发中的应用:原生模块和跨平台SDK

作者: IT Sectr 发布日期: 2026-02-11 阅读时间: 10 分钟

Rust — 一种在编译阶段提供内存安全保障的系统编程语言。由Mozilla Research于2010年在Graydon Hoare的领导下开发。Rust可以防止整类漏洞:空指针、悬垂引用和数据竞争。在移动开发中,Rust用于原生模块、跨平台SDK和WebAssembly。根据Stack Overflow Survey (2025)的数据,Rust已经连续九年位列「最受欢迎语言」榜首。

要点

  • Rust — 通过所有权(ownership)系统实现无垃圾回收器内存安全的系统语言
  • Borrow checker — 借用检查器,在编译阶段检查引用,防止数据竞争
  • 原生模块 在Rust中通过cargo-ndk和cargo-lipo编译为Android的.so和iOS的.a文件
  • WebAssembly (Wasm) 允许Rust代码在浏览器和移动设备上以接近原生的性能运行
  • FFI(外部函数接口) — 通过C兼容ABI从Java、Kotlin和Swift调用Rust的机制

什么是Rust?

Rust — 一种具有零成本抽象(zero-cost abstractions)的静态类型系统编程语言。Rust通过所有权(ownership)、借用(borrowing)和生命周期(lifetimes)系统保证了无垃圾回收器的内存安全。Rust编译器是最严格的编译器之一——它会拒绝那些在C++中会导致未定义行为的代码。

Rust通过LLVM编译为所有架构的原生代码:ARM、x86、RISC-V、WebAssembly。工具链:rustup(安装器)、rustc(编译器)、cargo(包管理器和构建工具)。cargo.toml——类似于package.json,包含来自crates.io的依赖项。当前版本——Rust 1.81(2025)。

Rust在移动开发中的关键应用领域:原生库(Android NDK、iOS)、跨平台SDK(Firefox、Dropbox)、在性能关键部分替代C++、用于混合应用的WebAssembly。Google在AOSP(Android开源项目)中使用Rust构建蓝牙、Wi-Fi和NFC组件。

为移动开发安装和配置Rust

要为Android进行交叉编译,需要目标工具链:rustup target add aarch64-linux-android armv7-linux-androideabi。iOS需要——aarch64-apple-ios x86_64-apple-ios。cargo-ndk(用于Android)和cargo-lipo(用于iOS)简化了构建过程。

sh
# 为移动开发安装Rust和目标平台
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
$ rustup target add aarch64-linux-android
$ rustup target add armv7-linux-androideabi
$ rustup target add aarch64-apple-ios
$ rustup target add x86_64-apple-ios

# 安装用于Android构建的cargo-ndk
$ cargo install cargo-ndk

# Android构建
$ cargo ndk -t arm64-v8a -o ./jniLibs build --release

所有权系统:ownership、borrowing和lifetimes

Ownership(所有权) — Rust的基本概念。每个值都恰好有一个所有者。在赋值或传递给函数时,所有权被转移(move)。转移后,原所有者不能使用该值。这消除了双重释放内存和悬垂指针的问题。

Borrowing(借用) 允许临时使用对值的引用而不转移所有权。&T引用(不可变)——任意数量的读取者。&mut T引用(可变)——恰好一个写入者,没有读取者。编译器在构建阶段检查这些规则。

rust
fn process_data(data: &mut Vec<i32>) {
    for item in data.iter_mut() {
        *item *= 2;
    }
}

fn main() {
    let mut numbers = vec![1, 2, 3, 4, 5];
    process_data(&mut numbers);
    println!("已处理:{:?}", numbers);

    let first = &numbers[0];  // 不可变借用
    println!("第一个:{}", first);
}

process_data接受一个可变的Vec引用并将每个元素加倍。iter_mut()返回一个包含可变引用的迭代器。*item解引用该引用以进行赋值。在process_data之后,numbers仍然可用——所有权没有被转移,只是被借用了。

Lifetimes:引用的生命周期

Lifetimes ('a) — 用于绑定引用生命周期的注解。编译器使用它们来检查引用不会比它指向的数据活得更久。在大多数情况下,生命周期是自动推断的——只需在带有引用的函数签名中指定它们。

rust
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() { x } else { y }
}

fn main() {
    let string1 = String::from("rust");
    let result;
    {
        let string2 = String::from("mobile");
        result = longest(string1.as_str(), string2.as_str());
        println!("最长的:{}", result);
    } // string2存活到此括号之前,result在内部有效
    // println!("{}", result); // 错误:string2已死
}

Rust用于Android和iOS原生模块

Rust 编译为Android的原生库(通过NDK生成.so)和iOS的静态库(.a)。Google在Android开源项目(AOSP)中官方支持Rust——蓝牙(ava)、DNS-over-HTTP3和CriticalNotification组件都用Rust编写。据Google(2025)称,Rust在Android中已将目标组件中的内存漏洞减少了70%。

对于Android,使用cargo-ndk,它为所选ABI封装了带有正确工具链的Cargo。Android的构建包括:aarch64-linux-android(64位ARM,现代设备)、armv7-linux-androideabi(32位ARM)、x86_64-linux-android(模拟器)。

rust
// Cargo.toml — Android/iOS库配置
[package]
name = "mobile_crypto"
version = "0.1.0"

[lib]
crate-type = ["staticlib", "cdylib"]

[dependencies]
serde = { version = "1", features = ["derive"] }
libc = "0.2"

crate-type:staticlib——用于iOS(.a),cdylib——用于Android(.so)。serde——用于与Kotlin/Swift数据交换的序列化。libc——用于FFI的C兼容类型。

示例:在Rust中处理图像

rust
use std::ffi::{CStr, CString};
use std::os::raw::c_char;

/// 用于图像处理的C兼容函数
#[no_mangle]
pub unsafe extern "C" fn process_image(
    input: *const u8,
    len: usize,
    output: *mut u8,
    out_len: *mut usize,
) {
    let input_slice = std::slice::from_raw_parts(input, len);
    let result: Vec<u8> = input_slice.iter()
        .map(|b| b ^ 0xFF)
        .collect();
    let result_len = result.len();
    std::ptr::copy_nonoverlapping(result.as_ptr(), output, result_len);
    *out_len = result_len;
}

#[no_mangle]为C兼容ABI禁用名称修饰。extern "C"设置C调用约定。unsafe——标记来自Rust外部的调用不保证安全性。std::ptr::copy_nonoverlapping将结果字节复制到输出缓冲区。

Rust中的跨平台SDK

Rust 是跨平台SDK的理想候选者,这些SDK从单一代码库在Android和iOS上运行。Mozilla(Firefox)、Dropbox(文件同步)和Meta(Libra区块链)等公司选择Rust来构建其移动应用的关键组件。

Rust库相对于C++的优势:编译器保证跨平台代码中没有内存泄漏和数据竞争。在Rust中编写和测试一次的代码在所有平台上运行相同。Cargo原生管理依赖项,无需CMake和vcpkg。

库/Crate用途
tonicRust中的gRPC客户端/服务器
reqwest支持async/await的HTTP客户端
ring密码学(AES、RSA、ECDSA)
sqlx异步操作SQLite、PostgreSQL
wasm-bindgenRust与JavaScript/WASM的集成
ndk-glueRust中的Android NativeActivity
uniffi为Kotlin/Swift生成FFI绑定

Rust和WebAssembly用于移动应用

Rust 编译为WebAssembly(Wasm)——一种可在浏览器和移动设备上执行的二进制格式。Wasm在Web环境中提供接近原生的性能。在移动开发中,Wasm用于混合应用(WebView + Wasm)中的复杂计算:3D渲染、图像识别、加密。

wasm-pack将Rust编译为.wasm并生成JS包装器。wasm-bindgen将Rust函数与JavaScript调用连接起来。在移动设备上,Wasm-runner可以在WebView中或通过Wasmer/Wasmtime SDK运行。

rust
use wasm_bindgen::prelude::*;

/// 在Wasm中计算斐波那契数(从JS调用)
#[wasm_bindgen]
pub fn fibonacci(n: u32) -> u64 {
    match n {
        0 => 0,
        1 => 1,
        _ => {
            let mut a = 0;
            let mut b = 1;
            for _ in 2..=n {
                let temp = a + b;
                a = b;
                b = temp;
            }
            b
        }
    }
}

#[wasm_bindgen]为fibonacci函数生成JavaScript包装器。在浏览器中,调用看起来像wasm.fibonacci(10)。u32/u64类型会自动转换为Number/BigInt。这样的函数的Wasm模块大约为5KB——开销极小。

FFI:从Kotlin和Swift调用Rust

FFI(外部函数接口) — 从其他语言调用Rust代码的机制。带有extern "C"和#[no_mangle]的Rust函数以C兼容ABI导出。从Kotlin中,此类函数通过JNI调用,从Swift中——通过@_cdecl("name")或CBridge.h调用。

UniFFI — Mozilla用于生成FFI绑定的工具。您在.udl文件中描述API,UniFFI自动生成Kotlin和Swift包装器。这是Firefox Android和Firefox iOS中Rust组件的标准方法。

rust
// 带有UniFFI接口的Rust库
uniffi::setup_scaffolding!();

#[derive(uniffi::Enum)]
pub enum EncryptionError {
    InvalidKey,
    EncryptionFailed,
}

#[derive(uniffi::Record)]
pub struct EncryptedData {
    pub ciphertext: Vec<u8>,
    pub nonce: Vec<u8>,
}

#[uniffi::export]
pub fn encrypt(key: &[u8], plaintext: &[u8]) -> Result<EncryptedData, EncryptionError> {
    // AES-256-GCM实现
    todo!()
}

UniFFI生成一个Kotlin类,其中包含接受ByteArray并返回EncryptedData的encrypt方法。在Swift中,创建了一个具有ciphertext(Data)和nonce(Data)字段的EncryptedData结构体。错误被转换为Kotlin/Swift异常。

Rust vs C++:移动开发对比

RustC++ — 移动开发中系统编程的两种主要语言。两者都编译为ARM的原生代码并通过C ABI支持FFI。主要区别——内存安全模型:Rust在编译阶段检查它,C++依赖开发人员的自律。

标准RustC++
内存安全有保障(ownership)开发人员责任
垃圾回收器无(RAII + ownership)无(手动管理)
内存泄漏编译器防止可能(new没有delete)
数据竞争防止(Send + Sync)可能
Android NDK通过cargo-ndk通过CMake / NDK Build
iOS支持cargo-lipo + .aXcode + .a
构建Cargo(内置)CMake / Ninja
构建时间2–5分钟(clean)5–15分钟(clean)
生态系统crates.io(200k+ crate)vcpkg / Conan(100k+ 库)

Rust比C++更安全、更高效——编译器捕获那些在C++中会在运行时出现的错误。C++拥有更丰富的移动库生态系统。对于新项目,Rust更受青睐;现有的C++代码逐步移植。

常见问题

Rust在移动开发方面与C++有何不同?

主要区别——编译时的内存安全性。在Rust中,由于所有权(ownership)系统和borrow checker,没有nullptr、悬垂指针和数据竞争。C++依赖开发人员的自律,Rust依赖编译器的检查。

Rust可以用于Android开发吗?

可以,通过Android NDK。Google在AOSP(Android开源项目)中官方支持Rust。Rust通过cargo-ndk编译为.so库。通过JNI的FFI(外部函数接口)与C++的工作方式相同。

什么是cargo?它如何帮助Rust开发?

Cargo — Rust的包管理器和构建系统。它从crates.io下载依赖项,编译项目并运行测试。在移动开发中,cargo-ndk扩展了Cargo以支持Android ABI的交叉编译。

Rust适用于iOS还是仅适用于Android?

Rust支持两个平台。对于iOS,使用cargo-lipo生成通用二进制文件(arm64 + x86_64模拟器)。Rust代码编译为静态库.a并通过Xcode链接。

2026年学习Rust用于移动开发值得吗?

值得,Rust正在成为跨平台SDK和原生模块的标准。Google、Meta和Mozilla都在投资Rust。对于性能关键组件,Rust比C++更安全、更高效。

总结

  • Rust — 通过ownership、borrowing和lifetimes实现无GC内存安全的系统语言
  • Borrow checker 在编译时防止数据竞争和悬垂指针
  • 原生模块 通过cargo-ndk(Android .so)和cargo-lipo(iOS .a)构建
  • UniFFI 为Kotlin和Swift生成FFI绑定——Mozilla移动SDK的标准
  • WebAssembly 允许Rust在移动WebView中以接近原生的性能运行
  • Google在AOSP中使用Rust — 目标组件中的内存漏洞减少了70%
  • Rust vs C++:Rust更安全,C++生态系统更丰富;新的原生模块选择Rust

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读