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 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.
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.
| Criterium | C++ | Java / Kotlin |
|---|---|---|
| Geheugenbeheer | Handmatig (new/delete, RAII) | Automatisch (Garbage Collector) |
| Compilatie | Native machinecode | JVM / ART-bytecode |
| Prestaties | Maximaal (zero-cost abstractions) | Hoog met GC-pauzes |
| Gebruik in mobiele ontwikkeling | NDK, games, bibliotheken | UI-apps, bedrijfslogica |
| Build | CMake, NDK Build, Gradle + NDK | Gradle, Maven |
| Cross-platform | Compilatie voor elk platform | JVM / ART overal |
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.
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.
// 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.
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.
android {
defaultConfig {
ndk {
abiFilters "arm64-v8a", "armeabi-v7a"
}
}
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
version "3.22.1"
}
}
}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 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.
// 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 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.
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 (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.
// 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.
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 — 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.
# 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 — 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.
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.
// 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.
| Bewerking | C++ (ms) | Java/Kotlin (ms) | Versnelling |
|---|---|---|---|
| Beeldverwerking 1920x1080 | 12 | 45 | 3,75x |
| Snelle Fourier-transformatie (FFT) | 8 | 34 | 4,25x |
| AES-256-versleuteling van 1MB-blok | 3 | 18 | 6x |
| ZLIB-gegevenscompressie | 5 | 22 | 4,4x |
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.
// 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
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.
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.
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.
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.
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
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.