Rust in mobiele ontwikkeling: native modules en cross-platform SDK's

Auteur: IT Sectr Gepubliceerd: 2026-02-11 Leestijd: 10 min

Rust — een systeemprogrammeertaal met geheugenveiligheidsgaranties tijdens compilatie. Ontwikkeld door Mozilla Research in 2010 onder leiding van Graydon Hoare. Rust voorkomt hele klassen kwetsbaarheden: null-pointers, dangling referenties en dataraces. In mobiele ontwikkeling wordt Rust gebruikt voor native modules, cross-platform SDK's en WebAssembly. Volgens Stack Overflow Survey (2025) staat Rust voor het negende jaar op rij op de eerste plaats als 'favoriete taal'.

Belangrijkste punten

  • Rust — systeemtaal met geheugenveiligheid zonder garbage collector via het ownership-systeem
  • Borrow checker — analyseert leningen, controleert referenties tijdens compilatie en voorkomt dataraces
  • Native modules in Rust worden gecompileerd naar .so voor Android en .a voor iOS via cargo-ndk en cargo-lipo
  • WebAssembly (Wasm) laat Rust-code draaien in de browser en op mobiele apparaten met near-native prestaties
  • FFI (Foreign Function Interface) — mechanisme om Rust aan te roepen vanuit Java, Kotlin en Swift via C-compatibele ABI

Wat is Rust?

Rust — een statisch getypeerde systeemprogrammeertaal met zero-cost abstractions. Rust garandeert geheugenveiligheid zonder garbage collector dankzij het systeem van ownership, borrowing en lifetimes. De Rust-compiler is een van de strengste — hij wijst code af die in C++ ongedefinieerd gedrag zou veroorzaken.

Rust compileert via LLVM naar native code voor alle architecturen: ARM, x86, RISC-V, WebAssembly. Tools: rustup (installatie), rustc (compiler), cargo (pakketbeheerder en bouwsysteem). cargo.toml — analoog aan package.json, bevat afhankelijkheden van crates.io. Huidige versie — Rust 1.81 (2025).

Belangrijkste toepassingsgebieden van Rust in mobiele ontwikkeling: native bibliotheken (Android NDK, iOS), cross-platform SDK's (Firefox, Dropbox), vervanging van C++ in performance-critical secties, WebAssembly voor hybride apps. Google gebruikt Rust in AOSP (Android Open Source Project) voor Bluetooth-, Wi-Fi- en NFC-componenten.

Installatie en configuratie van Rust voor mobiele ontwikkeling

Voor cross-compilatie naar Android zijn doel-toolchains nodig: rustup target add aarch64-linux-android armv7-linux-androideabi. Voor iOS — aarch64-apple-ios x86_64-apple-ios. cargo-ndk (voor Android) en cargo-lipo (voor iOS) vereenvoudigen de build.

sh
# Installatie van Rust en doelplatformen voor mobiele ontwikkeling
$ 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

# Installatie van cargo-ndk voor Android-build
$ cargo install cargo-ndk

# Builden voor Android
$ cargo ndk -t arm64-v8a -o ./jniLibs build --release

Eigenaarschap: ownership, borrowing en lifetimes

Ownership (eigenaarschap) — het fundamentele concept van Rust. Elke waarde heeft precies één eigenaar. Bij toewijzing of overdracht aan een functie wordt het eigenaarschap verplaatst (move). Na verplaatsing kan de oude eigenaar de waarde niet meer gebruiken. Dit elimineert dubbel vrijgeven van geheugen en dangling pointers.

Borrowing (lenen) maakt tijdelijk gebruik van een referentie naar een waarde mogelijk zonder overdracht van eigenaarschap. Referentie &T (immutable) — onbeperkt aantal lezers. Referentie &mut T (mutable) — precies één schrijver, geen lezers. De compiler controleert deze regels tijdens de buildfase.

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!("Verwerkt: {:?}", numbers);

    let first = &numbers[0];  // immutable lening
    println!("Eerste: {}", first);
}

process_data neemt een mutable referentie naar Vec en verdubbelt elk element. iter_mut() retourneert een iterator met mutable referenties. *item derefereert de referentie voor toewijzing. Na process_data blijft numbers beschikbaar — eigenaarschap is niet verplaatst, alleen geleend.

Lifetimes: levensduur van referenties

Lifetimes ('a) — annotaties om levensduren van referenties te koppelen. De compiler gebruikt ze om te controleren of een referentie niet langer leeft dan de data waarnaar hij verwijst. In de meeste gevallen worden lifetimes automatisch afgeleid — ze moeten alleen worden opgegeven in functiehandtekeningen met referenties.

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!("Langste: {}", result);
    } // string2 leeft tot deze haak, result is geldig binnenin
    // println!("{}", result); // fout: string2 is dood
}

Rust voor native Android- en iOS-modules

Rust compileert naar native bibliotheken voor Android (.so via NDK) en iOS (.a statische bibliotheken). Google ondersteunt Rust officieel in Android Open Source Project (AOSP) — Bluetooth (ava), DNS-over-HTTP3 en CriticalNotification zijn in Rust geschreven. Volgens Google (2025) heeft Rust in Android 70% van de geheugenkwetsbaarheden in doelcomponenten geëlimineerd.

Voor Android wordt cargo-ndk gebruikt, dat Cargo omhult met de juiste toolchain voor de gekozen ABI. Builden voor Android omvat: aarch64-linux-android (64-bit ARM, moderne apparaten), armv7-linux-androideabi (32-bit ARM), x86_64-linux-android (emulators).

rust
// Cargo.toml — configuratie van bibliotheek voor 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 — voor iOS (.a), cdylib — voor Android (.so). serde — serialisatie voor gegevensuitwisseling met Kotlin/Swift. libc — C-compatibele types voor FFI.

Voorbeeld: beeldverwerking in Rust

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

/// C-compatibele functie voor beeldverwerking
#[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] schakelt name mangling uit voor C-compatibele ABI. extern "C" stelt de C-aanroepconventie in. unsafe — markering dat aanroep van buiten Rust geen veiligheid garandeert. std::ptr::copy_nonoverlapping kopieert resultaatbytes naar de uitvoerbuffer.

Cross-platform SDK's in Rust

Rust — de ideale kandidaat voor cross-platform SDK's die op Android en iOS werken vanaf één codebase. Bedrijven als Mozilla (Firefox), Dropbox (bestandssynchronisatie) en Meta (Libra blockchain) hebben Rust gekozen voor kritieke componenten van hun mobiele apps.

Voordelen van een Rust-bibliotheek ten opzichte van C++: de compiler garandeert afwezigheid van geheugenlekken en dataraces in cross-platform code. Eenmaal geschreven en geteste code in Rust werkt identiek op alle platformen. Cargo beheert afhankelijkheden native, zonder CMake en vcpkg.

Bibliotheek/CrateDoel
tonicgRPC-client/server in Rust
reqwestHTTP-client met async/await
ringCryptografie (AES, RSA, ECDSA)
sqlxAsynchroon werken met SQLite, PostgreSQL
wasm-bindgenIntegratie van Rust met JavaScript/WASM
ndk-glueAndroid NativeActivity in Rust
uniffiGenereren van FFI-bindingen voor Kotlin/Swift

Rust en WebAssembly voor mobiele apps

Rust compileert naar WebAssembly (Wasm) — een binair formaat dat uitvoerbaar is in de browser en op mobiele apparaten. Wasm biedt near-native prestaties in de webomgeving. In mobiele ontwikkeling wordt Wasm gebruikt in hybride apps (WebView + Wasm) voor complexe berekeningen: 3D-rendering, beeldherkenning, encryptie.

wasm-pack compileert Rust naar .wasm en genereert een JS-wrapper. wasm-bindgen verbindt Rust-functies met JavaScript-aanroepen. Op een mobiel apparaat kan Wasm-runner draaien in WebView of via Wasmer/Wasmtime SDK's.

rust
use wasm_bindgen::prelude::*;

/// Berekenen van Fibonacci-getal in Wasm (aangeroepen vanuit 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] genereert een JavaScript-wrapper voor de functie fibonacci. In de browser ziet de aanroep eruit als wasm.fibonacci(10). Types u32/u64 worden automatisch geconverteerd naar Number/BigInt. De Wasm-module weegt ~5 KB voor zo'n functie — minimale overhead.

FFI: Rust aanroepen vanuit Kotlin en Swift

FFI (Foreign Function Interface) — het mechanisme om Rust-code aan te roepen vanuit andere talen. Rust-functies met extern "C" en #[no_mangle] worden geëxporteerd met C-compatibele ABI. Vanuit Kotlin worden dergelijke functies aangeroepen via JNI, vanuit Swift via @_cdecl ("name") of CBridge.h.

UniFFI — Mozilla's tool voor het genereren van FFI-bindingen. Je beschrijft de API in een .udl-bestand, UniFFI genereert automatisch Kotlin- en Swift-wrappers. Dit is de standaardaanpak voor Rust-componenten in Firefox Android en Firefox iOS.

rust
// Rust-bibliotheek met UniFFI-interface
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> {
    // implementatie van AES-256-GCM
    todo!()
}

UniFFI genereert een Kotlin-klasse met de methode encrypt die ByteArray ontvangt en EncryptedData retourneert. In Swift wordt een struct EncryptedData aangemaakt met velden ciphertext (Data) en nonce (Data). Fouten worden omgezet in Kotlin/Swift-uitzonderingen.

Rust versus C++: vergelijking voor mobiele ontwikkeling

Rust en C++ — de twee belangrijkste talen voor systeemprogrammeren in mobiele ontwikkeling. Beide compileren naar native code voor ARM en ondersteunen FFI via C ABI. Het belangrijkste verschil — het geheugenveiligheidsmodel: Rust controleert dit tijdens compilatie, C++ vertrouwt op de discipline van de ontwikkelaar.

CriteriumRustC++
GeheugenveiligheidGegarandeerd (ownership)Verantwoordelijkheid ontwikkelaar
Garbage collectorNee (RAII + ownership)Nee (handmatig beheer)
GeheugenlekkenVoorkomen door compilerMogelijk (new zonder delete)
DataracesVoorkomen (Send + Sync)Mogelijk
Android NDKVia cargo-ndkVia CMake / NDK Build
iOS-ondersteuningcargo-lipo + .aXcode + .a
BuildsysteemCargo (ingebouwd)CMake / Ninja
Bouwtijd2–5 min (clean)5–15 min (clean)
Ecosysteemcrates.io (200k+ crates)vcpkg / Conan (100k+ bibliotheken)

Rust is veiliger dan C++ en productiever — de compiler vangt fouten die in C++ tijdens runtime zouden verschijnen. C++ heeft een rijker ecosysteem van mobiele bibliotheken. Voor nieuwe projecten heeft Rust de voorkeur; bestaande C++-code wordt geleidelijk geporteerd.

Veelgestelde vragen

Waarin verschilt Rust van C++ voor mobiele ontwikkeling?

Het belangrijkste verschil — geheugenveiligheid tijdens compilatie. In Rust zijn er geen nullptr, dangling pointers en dataraces dankzij het ownership-systeem en borrow checker. C++ vertrouwt op de discipline van de ontwikkelaar, Rust — op compilercontroles.

Kan Rust worden gebruikt in Android-ontwikkeling?

Ja, via Android NDK. Google ondersteunt Rust officieel in AOSP (Android Open Source Project). Rust wordt gecompileerd naar .so-bibliotheken via cargo-ndk. FFI (Foreign Function Interface) via JNI werkt hetzelfde als voor C++.

Wat is cargo en hoe helpt het bij Rust-ontwikkeling?

Cargo — de pakketbeheerder en het buildsysteem van Rust. Het downloadt afhankelijkheden van crates.io, compileert het project en voert tests uit. In mobiele ontwikkeling breidt cargo-ndk Cargo uit voor cross-compilatie naar Android ABI.

Is Rust geschikt voor iOS of alleen voor Android?

Rust ondersteunt beide platformen. Voor iOS wordt cargo-lipo gebruikt voor universele binaire bestanden (arm64 + x86_64 simulator). Rust-code wordt gecompileerd naar een statische bibliotheek .a en gelinkt via Xcode.

Is het de moeite waard om Rust te leren voor mobiele ontwikkeling in 2026?

Ja, Rust wordt een standaard voor cross-platform SDK's en native modules. Google, Meta en Mozilla investeren in Rust. Voor performance-critical componenten is Rust veiliger en productiever dan C++.

Samenvatting

  • Rust — systeemtaal met geheugenveiligheid zonder GC dankzij ownership, borrowing en lifetimes
  • Borrow checker voorkomt dataraces en dangling pointers tijdens compilatie
  • Native modules worden gebouwd via cargo-ndk (Android .so) en cargo-lipo (iOS .a)
  • UniFFI genereert FFI-bindingen voor Kotlin en Swift — Mozilla-standaard voor mobiele SDK's
  • WebAssembly laat Rust draaien in mobiele WebViews met near-native prestaties
  • Google gebruikt Rust in AOSP — geheugenkwetsbaarheden in doelcomponenten met 70% verminderd
  • Rust vs C++: Rust veiliger, C++ met rijker ecosysteem; voor nieuwe native modules kiest men Rust

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook