C++ est un langage de programmation multi-paradigme avec gestion manuelle de la mémoire, combinant la programmation procédurale, orientée objet et générique. Dans le développement mobile, le C++ est utilisé via Android NDK pour porter des bibliothèques et via les moteurs de jeux Unity et Unreal Engine pour créer des jeux multiplateformes. Selon TIOBE (2026), le C++ figure parmi les 5 langages les plus populaires parmi les développeurs professionnels.
Points clés
C++ est un langage de programmation créé par Bjarne Stroustrup en 1985 comme une extension du langage C avec support des classes. Le C++ offre un accès direct à la mémoire via les pointeurs, la métaprogrammation de templates et l'héritage multiple. Les normes C++17 et C++20 ont ajouté les coroutines, les concepts et les ranges.
Contrairement à Java et Kotlin, le C++ n'a pas de ramasse-miettes — le développeur gère manuellement l'allocation et la libération de la mémoire via les opérateurs new et delete. Cela donne un contrôle total sur les performances mais exige de la discipline. Selon l'enquête JetBrains Developer Survey (2025), 42% des développeurs C++ utilisent le langage dans l'industrie du jeu vidéo.
Les normes C++ évoluent tous les trois ans : C++11 (lambdas, auto, unique_ptr), C++14 (lambdas génériques), C++17 (if constexpr, filesystem), C++20 (modules, coroutines, concepts). Les compilateurs Clang et GCC supportent toutes les normes actuelles, et Android NDK utilise Clang de la chaîne d'outils LLVM.
La principale différence entre C++ et les langages JVM est la gestion manuelle de la mémoire et la compilation directe en code machine. Java et Kotlin fonctionnent sur une machine virtuelle avec ramasse-miettes automatique. Le code C++ se compile en un binaire natif pour une architecture spécifique — ARM, x86 ou RISC-V.
| Critère | C++ | Java / Kotlin |
|---|---|---|
| Gestion mémoire | Manuelle (new/delete, RAII) | Automatique (ramasse-miettes) |
| Compilation | Code machine natif | Bytecode JVM / ART |
| Performances | Maximales (abstractions sans coût) | Élevées avec pauses GC |
| Utilisation en développement mobile | NDK, jeux, bibliothèques | Applications UI, logique métier |
| Compilation | CMake, NDK Build, Gradle + NDK | Gradle, Maven |
| Multiplateforme | Compiler pour chaque plateforme | JVM / ART partout |
Android NDK (Native Development Kit) est une boîte à outils de Google pour écrire des parties d'applications Android en C et C++. Le NDK inclut une chaîne d'outils basée sur Clang, des fichiers d'en-tête système Android et des bibliothèques de débogage et de profilage. La version r27 (2025) supporte C++20 et utilise LLVM 18.
Le NDK compile le code C++ en bibliothèques dynamiques .so pour les architectures ARM64, ARM32, x86 et x86_64. Une application Java ou Kotlin charge ces bibliothèques via System.loadLibrary() et appelle des fonctions natives via JNI. Selon Google, le NDK a été téléchargé plus de 5 millions de fois.
Un projet typique avec Android NDK contient le dossier app/src/main/cpp/ avec les fichiers source C++, CMakeLists.txt pour la compilation et une classe Java avec déclaration de méthodes natives. Gradle connecte le NDK via le bloc externalNativeBuild dans build.gradle.
// native-lib.cpp — méthode JNI simple pour 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());
}Le code déclare une fonction JNI avec le nom complet Java_com_example_app_MainActivity_stringFromJNI — c'est la convention de nommage JNI. La fonction prend un pointeur vers JNIEnv (l'environnement d'exécution) et jobject (l'instance de la classe appelante). env->NewStringUTF crée une chaîne Java à partir d'une chaîne C++.
Android supporte plusieurs ABI (Application Binary Interface) : arm64-v8a (périphériques ARM 64 bits, 99% des smartphones modernes), armeabi-v7a (ARM 32 bits, anciens appareils), x86_64 (émulateurs). Le NDK permet de compiler .so pour chaque architecture via des filtres ABI dans build.gradle.
android {
defaultConfig {
ndk {
abiFilters "arm64-v8a", "armeabi-v7a"
}
}
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
version "3.22.1"
}
}
}C++ est le langage principal des moteurs de jeux. Unreal Engine utilise C++ pour tout le code du jeu, tandis qu'Unity utilise C++ dans le noyau du moteur pour le rendu et la physique. Même si un développeur écrit en C# dans Unity, sous le capot C++ gère les graphiques, le son et les calculs physiques.
Unreal Engine est construit sur C++ depuis le début. Le code de la logique du jeu est écrit en C++ avec des macros UHT (Unreal Header Tool) pour l'intégration avec Blueprints — un système de script visuel. Les classes héritent des types de base AActor, UObject, UGameInstance avec les lettres de préfixe U, A, F.
// Classe de personnage dans Unreal Engine avec 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;
};Les macros UCLASS() et UPROPERTY() font partie du système de réflexion d'Unreal Engine. UHT (Unreal Header Tool) génère du code C++ à partir des fichiers d'en-tête pour la sérialisation, les blueprints et la réplication réseau. MoveSpeed s'affiche dans l'éditeur via UPROPERTY(EditAnywhere).
Unity utilise C# pour la logique du jeu, mais C++ est utilisé dans les plugins natifs — bibliothèques .so pour Android et .bundle pour iOS. Via Android NDK, on peut intégrer des SDK C++ pour les réseaux publicitaires, l'analytique ou porter des bibliothèques C++ de jeux desktop.
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);
}
}Dans cet exemple, C# marshale un appel à la fonction C++ ProcessFrame via P/Invoke. L'attribut DllImport spécifie le nom de la bibliothèque .so. La fonction C++ traite la trame en temps réel et retourne le résultat. Cette approche est utilisée pour les post-effets et la vision par ordinateur.
JNI (Java Native Interface) est le mécanisme standard pour appeler du code C/C++ depuis Java ou Kotlin. Sous Android, JNI est le seul moyen de transférer des données entre la machine virtuelle ART et une bibliothèque native. Chaque appel JNI a un coût, donc les données doivent être transférées par lots plutôt qu'un champ à la fois.
JNIEnv est un pointeur vers la table des fonctions JNI. env->FindClass charge une classe Java, env->GetMethodID obtient un identifiant de méthode, env->CallVoidMethod l'invoque. Pour les chaînes, utilisez GetStringUTFChars et ReleaseStringUTFChars. JNI supporte également les références globales et faibles vers des objets Java.
// Passer un tableau d'octets de C++ vers 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; // inverser les octets
}
env->ReleaseByteArrayElements(input, buffer, JNI_COMMIT);
}GetByteArrayElements obtient un pointeur vers le tableau d'octets Java. JNI_COMMIT dans ReleaseByteArrayElements copie les modifications dans le tableau Java sans libérer la mémoire. Le traitement de la boucle for s'exécute sur le CPU avec des performances C++ maximales sans pauses GC.
Le principal danger de JNI est les fuites de références globales. Chaque NewGlobalRef doit être libéré via DeleteGlobalRef. Les références locales (retournées par FindClass, NewStringUTF) sont automatiquement libérées au retour de la fonction native. Pour les appels intensifs, utilisez PushLocalFrame / PopLocalFrame.
CMake est l'outil de compilation principal pour C++ dans Android NDK. CMakeLists.txt décrit les cibles de compilation, les bibliothèques et les dépendances. Gradle invoque CMake via externalNativeBuild, en passant les chemins vers le NDK et la chaîne d'outils. Une alternative est NDK Build basé sur Android.mk et Application.mk.
CMake 3.22+ supporte les préréglages (CMakePresets.json) pour différentes configurations : debug, release, profile avec différents drapeaux d'optimisation. Pour Android, on utilise la chaîne d'outils android.toolchain.cmake du NDK, fournie automatiquement par Gradle lors de la compilation.
# CMakeLists.txt pour projet Android NDK
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) crée une bibliothèque .so. target_link_libraries lie les bibliothèques système android (pour JNI) et log (pour __android_log_print). La bibliothèque statique libjpeg.a est liée pour le traitement d'images JPEG. CXX_STANDARD 20 active le support de C++20.
vcpkg est un gestionnaire de paquets C++ de Microsoft qui supporte Android NDK comme plateforme cible. Via vcpkg, on peut installer Boost, OpenCV, SQLite, nlohmann-json et d'autres bibliothèques compilées pour Android ABI. Vcpkg s'intègre avec CMake via CMAKE_TOOLCHAIN_FILE.
C++ offre des performances maximales sur les appareils mobiles grâce à la compilation en code ARM natif et à l'absence de ramasse-miettes. Selon les tests de Google (Android Performance Patterns, 2024), le code JNI en C++ s'exécute 3 à 10 fois plus vite que le code Java équivalent pour les tâches à calculs intensifs.
Facteurs clés des performances C++ sur plateformes mobiles : localité de cache (disposition contiguë de la mémoire), instructions SIMD NEON pour ARM, communication JNI asynchrone via des files de messages. NEON est l'extension SIMD d'ARM, traitant 128 bits de données en une seule instruction, indispensable pour le traitement audio, vidéo et d'images.
// Traitement SIMD de tableau 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 charge 4 floats de la mémoire dans un registre NEON 128 bits. vmulq_f32 multiplie tous les 4 éléments par 0.5 en un cycle. vst1q_f32 stocke le résultat en retour. Sans SIMD, la même boucle effectuerait 4 multiplications séquentiellement — NEON offre jusqu'à 4x d'accélération pour ces opérations.
| Opération | C++ (ms) | Java/Kotlin (ms) | Accélération |
|---|---|---|---|
| Traitement d'image 1920x1080 | 12 | 45 | 3.75x |
| Transformée de Fourier rapide (FFT) | 8 | 34 | 4.25x |
| Chiffrement AES-256 d'un bloc 1 Mo | 3 | 18 | 6x |
| Compression de données ZLIB | 5 | 22 | 4.4x |
La première erreur et la plus dangereuse sont les fuites mémoire. Chaque new doit avoir un delete, chaque new[] doit avoir un delete[]. Sur les appareils mobiles avec RAM limitée, toute fuite entraîne un OOM (Out Of Memory) et un plantage de l'application. Utilisez RAII via les pointeurs intelligents : std::unique_ptr, std::shared_ptr, std::weak_ptr.
La deuxième erreur est l'ignorance de la compatibilité ABI. Une bibliothèque compilée pour armeabi-v7a ne se chargera pas sur un appareil ARM64. Spécifiez toujours abiFilters dans build.gradle et testez sur des appareils réels, pas seulement sur l'émulateur x86_64. Utilisez Android App Bundle pour le filtrage automatique ABI.
La troisième erreur courante est les appels JNI fréquents. Chaque transition entre Java et C++ coûte environ 50–100 ns. Si vous traitez un tableau de 10000 éléments un par un via JNI, la surcharge dépasse le travail utile. Passez les tableaux entiers d'un coup et traitez-les côté C++.
Les problèmes de threading sont une autre erreur fréquente. C++ peut lancer std::thread, mais JNI n'est accessible que depuis des threads créés par Java. Pour appeler des méthodes Java depuis un thread C++, utilisez AttachCurrentThread / DetachCurrentThread via JNI.
// Appeler correctement Java depuis un thread C++
JavaVM *g_vm; // pointeur global obtenu lors de 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();
}
}Questions fréquentes
Android NDK (Native Development Kit) est une boîte à outils pour écrire des parties d'applications en C ou C++. Il est utilisé pour les tâches critiques en performance, le portage de bibliothèques C/C++ vers Android et l'implémentation de code multiplateforme pour Unity et Unreal Engine.
Dans Unity, le code de la logique du jeu est écrit en C#, mais C++ est utilisé conjointement avec Android NDK pour les plugins, l'accélération matérielle, le portage de bibliothèques C++ personnalisées et l'intégration de SDK natifs pour la publicité et l'analytique.
CMakeLists.txt décrit les fichiers source, les bibliothèques et les drapeaux de compilation. La configuration minimale inclut add_library pour compiler .so et target_link_libraries pour lier le log Android et d'autres bibliothèques système.
JNI (Java Native Interface) est la couche entre le code Java/Kotlin d'une application Android et la bibliothèque C++. Si C++ est appelé depuis Java, JNI est obligatoire. On peut écrire du code C++ entièrement via NDK, mais le point d'entrée est généralement une Activity Java qui appelle des fonctions natives.
C++ est justifié pour les jeux, le traitement audio/vidéo en temps réel, la vision par ordinateur, la cryptographie, les simulations physiques et le portage de bibliothèques depuis d'autres plateformes. Pour une application UI classique, Kotlin est plus efficace et simple.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi