C++ in mobiele ontwikkeling: Android NDK, Unity en Unreal Engine

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

C++ — een multi-paradigma programmeertaal met handmatig geheugenbeheer, die procedureel, objectgeoriënteerd en generiek programmeren combineert. In mobiele ontwikkeling wordt C++ gebruikt via Android NDK voor het porteren van bibliotheken en via de game-engines Unity en Unreal Engine voor het maken van cross-platform games. Volgens TIOBE (2026) staat C++ in de top 5 van populairste talen onder professionele ontwikkelaars.

Belangrijkste punten

  • C++ — een systeemprogrammeertaal gebruikt in Android NDK, Unity en Unreal Engine
  • Android NDK maakt compilatie van C++-code naar native .so-bibliotheken voor ARM-processors mogelijk
  • Unreal Engine is volledig gebouwd op C++, en Unity gebruikt C++ voor low-level plugins
  • JNI (Java Native Interface) — de brug tussen Java/Kotlin en C++ op Android
  • CMake en NDK Build — buildsystemen voor C++-projecten op mobiele platformen

Wat is C++?

C++ — een programmeertaal gecreëerd door Bjarne Stroustrup in 1985 als uitbreiding van C met ondersteuning voor klassen. C++ biedt directe toegang tot geheugen via pointers, template-metaprogrammering en meervoudige overerving. De standaarden C++17 en C++20 voegden coroutines, concepten en ranges toe.

In tegenstelling tot Java en Kotlin heeft C++ geen garbage collector — de ontwikkelaar beheert handmatig geheugentoewijzing en -vrijgave via de operatoren new en delete. Dit geeft volledige controle over prestaties, maar vereist discipline. Volgens JetBrains Developer Survey (2025) gebruikt 42% van de C++-ontwikkelaars de taal in de game-industrie.

C++-standaarden evolueren elke drie jaar: C++11 (lambdas, auto, unique_ptr), C++14 (algemene lambdas), C++17 (if constexpr, filesystem), C++20 (modules, coroutines, concepten). De compilers Clang en GCC ondersteunen alle actuele standaarden, en voor Android NDK wordt Clang uit de LLVM-toolchain gebruikt.

Verschillen tussen C++ en Java en Kotlin

Het belangrijkste verschil van C++ met JVM-talen — handmatig geheugenbeheer en compilatie direct naar machinecode. Java en Kotlin draaien op een virtuele machine met automatische garbage collection. C++-code wordt gecompileerd naar een native binair bestand voor een specifieke architectuur — ARM, x86 of RISC-V.

CriteriumC++Java / Kotlin
GeheugenbeheerHandmatig (new/delete, RAII)Automatisch (Garbage Collector)
CompilatieNative machinecodeJVM / ART-bytecode
PrestatiesMaximaal (zero-cost abstractions)Hoog met GC-pauzes
Gebruik in mobiele ontwikkelingNDK, games, bibliothekenUI-apps, bedrijfslogica
BuildCMake, NDK Build, Gradle + NDKGradle, Maven
Cross-platformCompilatie voor elk platformJVM / ART overal

C++ in mobiele ontwikkeling: Android NDK

Android NDK (Native Development Kit) — Google's toolset voor het schrijven van delen van Android-apps in C en C++. NDK bevat een toolchain gebaseerd op Clang, systeemheaderbestanden van Android, bibliotheken voor debuggen en profilering. Versie r27 (2025) ondersteunt C++20 en gebruikt LLVM 18.

NDK compileert C++-code naar dynamische .so-bibliotheken voor ARM64-, ARM32-, x86- en x86_64-architecturen. Een Java- of Kotlin-app laadt deze bibliotheken via System.loadLibrary() en roept native functies aan via JNI. Volgens Google is NDK meer dan 5 miljoen keer gedownload.

Projectstructuur met NDK

Een typisch project met Android NDK bevat een map app/src/main/cpp/ met C++-bronbestanden, CMakeLists.txt voor de build en een Java-klasse met declaratie van native methoden. Gradle koppelt NDK via het externalNativeBuild-blok in build.gradle.

cpp
// native-lib.cpp — een eenvoudige JNI-methode voor Android
#include <jni.h>
#include <string>

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_app_MainActivity_stringFromJNI(
    JNIEnv *env,
    jobject /*thiz*/) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

De code declareert een JNI-functie met de volledige naam Java_com_example_app_MainActivity_stringFromJNI — dit is de JNI-naamgevingsconventie. De functie ontvangt een pointer naar JNIEnv (uitvoeringsomgeving) en jobject (instantie van de aanroepende klasse). env->NewStringUTF creëert een Java-string uit een C++-string.

ABI en doelarchitecturen

Android ondersteunt meerdere ABI's (Application Binary Interface): arm64-v8a (64-bit ARM-apparaten, 99% van moderne smartphones), armeabi-v7a (32-bit ARM, oudere apparaten), x86_64 (emulators). NDK maakt het mogelijk .so te bouwen voor elke architectuur via ABI-filters in build.gradle.

gradle
android {
    defaultConfig {
        ndk {
            abiFilters "arm64-v8a", "armeabi-v7a"
        }
    }
    externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
            version "3.22.1"
        }
    }
}

C++ en game-engines: Unity en Unreal Engine

C++ — de primaire taal van game-engines. Unreal Engine gebruikt C++ voor alle gamecode, en Unity gebruikt C++ in de enginekern voor rendering en fysica. Zelfs als een ontwikkelaar in C# in Unity schrijft, beheert C++ onder de motorkap graphics, geluid en fysieke berekeningen.

Unreal Engine: C++ als primaire taal

Unreal Engine is vanaf de grond opgebouwd in C++. Game-logic code wordt geschreven in C++ met behulp van UHT-macro's (Unreal Header Tool) voor integratie met Blueprints — een visueel scriptingsysteem. Klassen erven over van basistypen AActor, UObject, UGameInstance met prefix letters U, A, F.

cpp
// Personageklasse in Unreal Engine in C++
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "MyCharacter.generated.h"

UCLASS()
class AMyCharacter : public ACharacter
{
    GENERATED_BODY()

public:
    AMyCharacter();

    virtual void BeginPlay() override;
    virtual void Tick(float DeltaTime) override;

    UPROPERTY(EditAnywhere, Category = "Movement")
    float MoveSpeed = 600.0f;

protected:
    void SetupPlayerInputComponent(UInputComponent *PlayerInputComponent) override;
};

De macro's UCLASS() en UPROPERTY() — maken deel uit van het reflectiesysteem van Unreal Engine. UHT (Unreal Header Tool) genereert C++-code uit headerbestanden voor serialisatie, blueprints en netwerkreplicatie. MoveSpeed wordt weergegeven in de editor via UPROPERTY(EditAnywhere).

Unity: C++ in plugins en Native SDK

Unity gebruikt C# voor gamelogica, maar C++ wordt toegepast in Native Plugins — .so-bibliotheken voor Android en .bundle voor iOS. Via Android NDK kunnen C++ SDK's van advertentienetwerken, analytics worden aangesloten of een C++-bibliotheek uit desktopgames worden geporteerd.

csharp
using System.Runtime.InteropServices;
using UnityEngine;

public class NativeBridge : MonoBehaviour
{
    const string LIB_NAME = "native_plugin";

    [DllImport(LIB_NAME, CallingConvention = CallingConvention.Cdecl)]
    private static extern int ProcessFrame(
        int width, int height,
        IntPtr pixelData
    );

    void Update()
    {
        int result = ProcessFrame(Screen.width, Screen.height, IntPtr.Zero);
        Debug.Log("Frame processed: " + result);
    }
}

In dit voorbeeld marshaleert C# de aanroep naar de C++-functie ProcessFrame via P/Invoke. Het DllImport-attribuut specificeert de naam van de .so-bibliotheek. De C++-functie verwerkt het frame in realtime en retourneert het resultaat. Deze aanpak wordt gebruikt voor post-effecten en computer vision.

JNI: interactie tussen Java en C++

JNI (Java Native Interface) — het standaardmechanisme voor het aanroepen van C/C++-code vanuit Java of Kotlin. In Android is JNI de enige manier om gegevens uit te wisselen tussen de ART virtuele machine en een native bibliotheek. Elke JNI-aanroep heeft overhead, daarom worden gegevens in batches verzonden, niet veld voor veld.

JNIEnv — een pointer naar de JNI-functietabel. env->FindClass laadt een Java-klasse, env->GetMethodID verkrijgt de methode-ID, env->CallVoidMethod roept deze aan. Voor strings wordt GetStringUTFChars en ReleaseStringUTFChars gebruikt. JNI ondersteunt ook globale en zwakke referenties naar Java-objecten.

cpp
// Byte-array doorgeven van C++ naar Java via JNI
extern "C" JNIEXPORT void JNICALL
Java_com_example_app_ImageProcessor_processArray(
    JNIEnv *env, jobject /*thiz*/,
    jbyteArray input, jint length) {

    jbyte *buffer = env->GetByteArrayElements(input, nullptr);
    jsize size = env->GetArrayLength(input);

    for (jsize i = 0; i < size; ++i) {
        buffer[i] = buffer[i] ^ 0xFF; // bytes omkeren
    }

    env->ReleaseByteArrayElements(input, buffer, JNI_COMMIT);
}

GetByteArrayElements verkrijgt een pointer naar een Java-bytearray. JNI_COMMIT in ReleaseByteArrayElements kopieert wijzigingen terug naar de Java-array zonder geheugen vrij te geven. De for-lus verwerking vindt plaats op de CPU met maximale C++-prestaties zonder GC-pauzes.

Geheugenbeheer in JNI

Het grootste gevaar van JNI — lekken van globale referenties. Elke NewGlobalRef moet worden vrijgegeven via DeleteGlobalRef. Lokale referenties (teruggegeven door FindClass, NewStringUTF) worden automatisch verwijderd bij terugkeer uit de native functie. Voor intensieve aanroepen gebruikt u PushLocalFrame / PopLocalFrame.

CMake en buildsystemen voor C++ op Android

CMake — het primaire buildinstrument voor C++ in Android NDK. CMakeLists.txt beschrijft builddoelen, bibliotheken en afhankelijkheden. Gradle roept CMake aan via externalNativeBuild en geeft paden naar NDK en toolchain door. Alternatief — NDK Build gebaseerd op Android.mk en Application.mk.

CMake 3.22+ ondersteunt presets (CMakePresets.json) voor verschillende configuraties: debug, release, profile met verschillende optimalisatievlaggen. Voor Android wordt de toolchain android.toolchain.cmake uit NDK gebruikt, die automatisch door Gradle wordt ingevuld tijdens de build.

cmake
# CMakeLists.txt voor Android NDK-project
cmake_minimum_required(VERSION 3.22)
project("native-lib")

add_library(
    native-lib
    SHARED
    src/main/cpp/native-lib.cpp
    src/main/cpp/image_utils.cpp
)

target_include_directories(
    native-lib PRIVATE
    src/main/cpp/include
)

target_link_libraries(
    native-lib
    android
    log
    ${CMAKE_SOURCE_DIR}/libs/libjpeg.a
)

set_target_properties(
    native-lib PROPERTIES
    CXX_STANDARD 20
    CXX_STANDARD_REQUIRED ON
)

add_library(SHARED) creëert een .so-bibliotheek. target_link_libraries koppelt systeembibliotheken android (voor JNI) en log (voor __android_log_print). De statische bibliotheek libjpeg.a wordt gelinkt voor het werken met JPEG-afbeeldingen. CXX_STANDARD 20 schakelt C++20-ondersteuning in.

vcpkg en afhankelijkheidsbeheer

vcpkg — de pakketbeheerder voor C++ van Microsoft, die Android NDK ondersteunt als doelplatform. Via vcpkg kunnen Boost, OpenCV, SQLite, nlohmann-json en andere bibliotheken gecompileerd voor Android ABI worden geïnstalleerd. Vcpkg integreert met CMake via CMAKE_TOOLCHAIN_FILE.

Prestaties van C++ op mobiele apparaten

C++ biedt maximale prestaties op mobiele apparaten dankzij compilatie naar native ARM-code en de afwezigheid van een garbage collector. Volgens Google-tests (Android Performance Patterns, 2024) wordt JNI-code in C++ 3–10 keer sneller uitgevoerd dan equivalente Java-code voor rekeningintensieve taken.

Belangrijkste factoren voor C++-prestaties op mobiele platformen: cache-lokaliteit (plaatsing van gegevens in aaneengesloten geheugen), NEON SIMD-instructies voor ARM, asynchroon werken met JNI via berichtenwachtrijen. NEON — de SIMD-extensie van ARM, waarmee 128 bits aan gegevens in één instructie kunnen worden verwerkt, onmisbaar voor audio-, video- en beeldverwerking.

cpp
// SIMD-verwerking van array via NEON intrinsics
#include <arm_neon.h>

void process_audio_neon(float *data, size_t n) {
    for (size_t i = 0; i < n; i += 4) {
        float32x4_t vec = vld1q_f32(&data[i]);
        float32x4_t result = vmulq_f32(vec, vdupq_n_f32(0.5f));
        vst1q_f32(&data[i], result);
    }
}

vld1q_f32 laadt 4 floats uit het geheugen in een 128-bit NEON-register. vmulq_f32 vermenigvuldigt alle 4 elementen met 0,5 in één cyclus. vst1q_f32 slaat het resultaat terug op. Zonder SIMD zou dezelfde lus 4 vermenigvuldigingen sequentieel uitvoeren — NEON geeft tot 4x versnelling voor dergelijke bewerkingen.

BewerkingC++ (ms)Java/Kotlin (ms)Versnelling
Beeldverwerking 1920x108012453,75x
Snelle Fourier-transformatie (FFT)8344,25x
AES-256-versleuteling van 1MB-blok3186x
ZLIB-gegevenscompressie5224,4x

Veelgemaakte fouten bij C++ in mobiele projecten

De eerste en gevaarlijkste fout — geheugenlekken. Elke new moet een delete hebben, elke new[] — delete[]. Op mobiele apparaten met beperkt RAM leidt elk lek tot OOM (Out Of Memory) en een crash van de app. Gebruik RAII via slimme pointers: std::unique_ptr, std::shared_ptr, std::weak_ptr.

De tweede fout — negeren van ABI-compatibiliteit. Een bibliotheek gecompileerd voor armeabi-v7a zal niet laden op een ARM64-apparaat. Specificeer altijd abiFilters in build.gradle en test op echte apparaten, niet alleen op de x86_64-emulator. Gebruik Android App Bundle voor automatische ABI-filtering.

De derde veelgemaakte fout — frequente JNI-aanroepen. Elke overgang tussen Java en C++ kost ongeveer 50–100 ns. Als u een array van 10000 elementen een voor een verwerkt via JNI, zal de overhead het nuttige werk overtreffen. Stuur gegevens als volledige arrays en verwerk ze aan de C++-kant.

Problemen met multithreading — nog een veelvoorkomende fout. C++ kan std::thread starten, maar toegang tot JNI is alleen mogelijk vanuit een thread die door Java is gemaakt. Gebruik AttachCurrentThread / DetachCurrentThread via JNI om Java-methoden vanuit een C++-thread aan te roepen.

cpp
// Correct aanroepen van Java vanuit C++-thread
JavaVM *g_vm; // globale pointer, verkregen bij JNI_OnLoad

void background_task() {
    JNIEnv *env;
    jint res = g_vm->AttachCurrentThread(&env, nullptr);
    if (res == JNI_OK) {
        jclass clazz = env->FindClass("com/example/App");
        jmethodID mid = env->GetStaticMethodID(clazz, "onProgress", "(I)V");
        env->CallStaticVoidMethod(clazz, mid, 100);
        g_vm->DetachCurrentThread();
    }
}

Veelgestelde vragen

Wat is Android NDK en waarom wordt C++ erin gebruikt?

Android NDK (Native Development Kit) — een toolset voor het schrijven van delen van de app in C of C++. Het wordt gebruikt voor prestaties-kritische taken, het porteren van C/C++-bibliotheken naar Android en het implementeren van cross-platform code voor Unity en Unreal Engine.

Welke Unity-games worden in C++ geschreven?

In Unity wordt gamelogica-code in C# geschreven, maar C++ wordt gebruikt in combinatie met Android NDK voor plugins, werken met hardwareversnelling, het porteren van eigen C++-bibliotheken en integratie van native SDK's voor advertenties en analytics.

Hoe configureer ik CMakeLists.txt voor C++ op Android?

CMakeLists.txt beschrijft bronbestanden, bibliotheken en compilatievlaggen. Minimale configuratie omvat add_library voor het bouwen van .so en target_link_libraries voor het koppelen van Android log en andere systeembibliotheken.

Is JNI in C++ verplicht voor Android?

JNI (Java Native Interface) — de tussenlaag tussen de Java/Kotlin-code van de Android-app en de C++-bibliotheek. Als C++ vanuit Java wordt aangeroepen, is JNI verplicht. Men kan C++-code volledig via NDK schrijven, maar het toegangspunt is meestal een Java-activiteit die native functies aanroept.

Wanneer is C++ gerechtvaardigd in plaats van Kotlin in mobiele ontwikkeling?

C++ is gerechtvaardigd voor games, real-time audio/video verwerking, computer vision, cryptografie, fysica-simulaties en het porteren van bibliotheken van andere platformen. Voor een gewone UI-app is Kotlin efficiënter en eenvoudiger.

Samenvatting

  • C++ — een multi-paradigma taal met handmatig geheugenbeheer, gebruikt in Android NDK, Unity en Unreal Engine voor hoogwaardige code
  • Android NDK compileert C++ naar .so-bibliotheken voor ARM-architecturen met de Clang-toolchain van LLVM
  • Unreal Engine is volledig gebouwd op C++ met het UHT-reflectiesysteem, Unity gebruikt C++ in de rende- en fysicakern
  • JNI — de verplichte brug tussen Java/Kotlin en C++ op Android met de naamgevingsconventie Java___
  • CMake — het primaire buildsysteem voor C++ in NDK, met ondersteuning voor C++20 en Gradle-integratie
  • NEON SIMD biedt tot 4x versnelling van gegevensverwerking op ARM-processors via 128-bit vectorinstructies
  • Veelgemaakte fouten: geheugenlekken, onjuiste ABI in abiFilters, frequente JNI-aanroepen en multithreading zonder AttachCurrentThread

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