C++ a mobilfejlesztésben: Android NDK, Unity és Unreal Engine

Szerző: IT Sectr Megjelenés: 2026-02-10 Olvasási idő: 11 perc

C++ — egy többparadigmás programozási nyelv kézi memóriakezeléssel, amely egyesíti a procedurális, objektumorientált és generikus programozást. A mobilfejlesztésben a C++-t az Android NDK-n keresztül használják könyvtárak portolására, valamint a Unity és Unreal Engine játékmotorokon keresztül keresztplatformos játékok létrehozására. A TIOBE (2026) szerint a C++ a top 5 nyelv között van a professzionális fejlesztők körében.

Főbb pontok

  • C++ — rendszerprogramozási nyelv, amelyet az Android NDK, Unity és Unreal Engine használ
  • Android NDK lehetővé teszi a C++ kód natív .so könyvtárakká fordítását ARM processzorokhoz
  • Unreal Engine teljes egészében C++-ra épül, a Unity pedig alacsony szintű bővítményekhez használja a C++-t
  • JNI (Java Native Interface) — híd a Java/Kotlin és a C++ között Androidon
  • CMake és NDK Build — build rendszerek C++ projektekhez mobil platformokon

Mi az a C++?

C++ — egy programozási nyelv, amelyet Bjarne Stroustrup hozott létre 1985-ben a C nyelv osztálytámogatással való kiterjesztéseként. A C++ közvetlen memóriaelérést biztosít pointereken keresztül, sablon-metaprogramozást és többszörös öröklődést. A C++17 és C++20 szabványok korutinokat, koncepciókat és ranges-t adtak hozzá.

Ellentétben a Javával és Kotlinnel, a C++-nak nincs szemétgyűjtője — a fejlesztő kézzel kezeli a memória lefoglalását és felszabadítását a new és delete operátorokon keresztül. Ez teljes kontrollt ad a teljesítmény felett, de fegyelmet igényel. A JetBrains Developer Survey (2025) szerint a C++ fejlesztők 42%-a használja a nyelvet a játékiparban.

C++ szabványok háromévente fejlődnek: C++11 (lambdák, auto, unique_ptr), C++14 (általánosított lambdák), C++17 (if constexpr, filesystem), C++20 (modulok, korutinok, koncepciók). A Clang és GCC fordítók támogatják az összes aktuális szabványt, az Android NDK-hoz pedig a Clang-ot használják az LLVM toolchainből.

A C++ különbségei a Java és Kotlin között

A C++ fő különbsége a JVM nyelvekhez képest — kézi memóriakezelés és közvetlen gépi kódba fordítás. A Java és Kotlin virtuális gépen fut automatikus szemétgyűjtéssel. A C++ kód natív bináris fájlba fordul egy adott architektúrára — ARM, x86 vagy RISC-V.

KritériumC++Java / Kotlin
MemóriakezelésKézi (new/delete, RAII)Automatikus (Garbage Collector)
FordításNatív gépi kódJVM / ART bájtkód
TeljesítményMaximális (zero-cost abstractions)Magas GC szünetekkel
Használat mobilfejlesztésbenNDK, játékok, könyvtárakUI alkalmazások, üzleti logika
BuildCMake, NDK Build, Gradle + NDKGradle, Maven
KeresztplatformosságFordítás minden platformraJVM / ART mindenhol

C++ a mobilfejlesztésben: Android NDK

Android NDK (Native Development Kit) — a Google eszközkészlete Android-alkalmazások részeinek C és C++ nyelven történő írásához. Az NDK Clang-alapú toolchain-t, Android rendszerfejléc-fájlokat, hibakeresési és profilozó könyvtárakat tartalmaz. Az r27 (2025) verzió támogatja a C++20-at és az LLVM 18-at használja.

Az NDK a C++ kódot dinamikus .so könyvtárakká fordítja ARM64, ARM32, x86 és x86_64 architektúrákhoz. A Java vagy Kotlin alkalmazás ezeket a könyvtárakat a System.loadLibrary()-n keresztül tölti be, és a natív függvényeket JNI-n keresztül hívja meg. A Google szerint az NDK-t több mint 5 milliószor töltötték le.

A projekt szerkezete NDK-val

Egy tipikus Android NDK projekt tartalmaz egy app/src/main/cpp/ mappát C++ forrásfájlokkal, CMakeLists.txt-t a buildhez és egy Java osztályt natív metódusok deklarálásával. A Gradle az NDK-t az externalNativeBuild blokkon keresztül csatlakoztatja a build.gradle-ben.

cpp
// native-lib.cpp — egy egyszerű JNI metódus Androidhoz
#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());
}

A kód deklarál egy JNI függvényt a Java_com_example_app_MainActivity_stringFromJNI teljes névvel — ez a JNI elnevezési konvenció. A függvény fogad egy pointert a JNIEnv-re (végrehajtási környezet) és egy jobject-et (a hívó osztály példánya). Az env->NewStringUTF Java sztringet hoz létre egy C++ sztringből.

ABI és célarchitektúrák

Az Android több ABI-t (Application Binary Interface) támogat: arm64-v8a (64 bites ARM eszközök, a modern okostelefonok 99%-a), armeabi-v7a (32 bites ARM, régebbi eszközök), x86_64 (emulátorok). Az NDK lehetővé teszi a .so buildelését minden architektúrára ABI szűrőkön keresztül a build.gradle-ben.

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

C++ és játékmotorok: Unity és Unreal Engine

C++ — a játékmotorok elsődleges nyelve. Az Unreal Engine a teljes játékkódhoz C++-t használ, a Unity pedig a motor magjában használja a C++-t rendereléshez és fizikához. Még ha a fejlesztő C#-ban ír is a Unityben, a motorháztető alatt a C++ kezeli a grafikát, hangot és fizikai számításokat.

Unreal Engine: C++ elsődleges nyelvként

Az Unreal Engine a semmiből C++-ra épül. A játéklogika kódját C++-ban írják az UHT (Unreal Header Tool) makrók használatával a Blueprints-szel — vizuális szkriptelési rendszerrel — való integrációhoz. Az osztályok az AActor, UObject, UGameInstance alap típusokból örökölnek U, A, F előtag betűkkel.

cpp
// Karakter osztály az Unreal Engine-ben C++-ban
#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;
};

Az UCLASS() és UPROPERTY() makrók — az Unreal Engine reflexiós rendszerének részei. Az UHT (Unreal Header Tool) C++ kódot generál a fejlécfájlokból szerializációhoz, blueprintekhez és hálózati replikációhoz. A MoveSpeed az UPROPERTY(EditAnywhere) révén jelenik meg a szerkesztőben.

Unity: C++ bővítményekben és Native SDK-ban

Unity C#-ot használ a játéklogikához, de a C++ a Native Plugins-ben alkalmazzák — .so könyvtárak Androidhoz és .bundle iOS-hez. Az Android NDK-n keresztül csatlakoztathatók hirdetési hálózatok C++ SDK-i, analitika, vagy portolható C++ könyvtár asztali játékokból.

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);
    }
}

Ebben a példában a C# marshalingolja a C++ ProcessFrame függvény hívását P/Invoke-on keresztül. A DllImport attribútum megadja a .so könyvtár nevét. A C++ függvény valós időben feldolgozza a képkockát és visszaadja az eredményt. Ezt a megközelítést utóhatásokhoz és számítógépes látáshoz használják.

JNI: Java és C++ együttműködése

JNI (Java Native Interface) — a szabványos mechanizmus C/C++ kód hívására Java vagy Kotlin felől. Androidon a JNI az egyetlen mód az ART virtuális gép és a natív könyvtár közötti adatátvitelre. Minden JNI hívásnak van overhead-je, ezért az adatokat kötegekben továbbítják, nem mezőnként.

JNIEnv — egy pointer a JNI függvénytáblára. Az env->FindClass betölt egy Java osztályt, az env->GetMethodID lekéri a metódus azonosítóját, az env->CallVoidMethod meghívja azt. Sztringekhez a GetStringUTFChars és ReleaseStringUTFChars használatos. A JNI támogatja a globális és gyenge referenciákat Java objektumokra.

cpp
// Bájt tömb átadása C++-ból Java-ba JNI-n keresztül
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; // bájtok megfordítása
    }

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

A GetByteArrayElements lekér egy pointert a Java bájt tömbhöz. A JNI_COMMIT a ReleaseByteArrayElements-ben visszamásolja a változtatásokat a Java tömbbe a memória felszabadítása nélkül. A for ciklus feldolgozása a CPU-n történik maximális C++ teljesítménnyel, GC szünetek nélkül.

Memóriakezelés JNI-ben

A JNI fő veszélye — a globális referenciák szivárgása. Minden NewGlobalRef-et fel kell szabadítani a DeleteGlobalRef-en keresztül. A lokális referenciák (amelyeket a FindClass, NewStringUTF ad vissza) automatikusan törlődnek a natív függvényből való visszatéréskor. Intenzív hívásokhoz használja a PushLocalFrame / PopLocalFrame függvényeket.

CMake és build rendszerek C++-hoz Androidon

CMake — a fő build eszköz a C++-hoz az Android NDK-ban. A CMakeLists.txt leírja a build célokat, könyvtárakat és függőségeket. A Gradle a CMake-t az externalNativeBuild-en keresztül hívja meg, átadva az NDK és a toolchain elérési útjait. Alternatíva — az Android.mk és Application.mk alapú NDK Build.

A CMake 3.22+ támogatja a preseteket (CMakePresets.json) különböző konfigurációkhoz: debug, release, profile különböző optimalizálási kapcsolókkal. Androidhoz az NDK-ból származó android.toolchain.cmake toolchain-t használják, amelyet a Gradle automatikusan helyettesít a build során.

cmake
# CMakeLists.txt Android NDK projekthez
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
)

Az add_library(SHARED) létrehoz egy .so könyvtárat. A target_link_libraries csatlakoztatja a rendszerkönyvtárakat: android (JNI-hez) és log (__android_log_print-hez). A libjpeg.a statikus könyvtár JPEG képek kezeléséhez van linkelve. A CXX_STANDARD 20 bekapcsolja a C++20 támogatást.

vcpkg és függőségkezelés

vcpkg — a Microsoft csomagkezelője C++-hoz, amely támogatja az Android NDK-t célplatformként. A vcpkg-n keresztül telepíthető a Boost, OpenCV, SQLite, nlohmann-json és más, Android ABI-ra fordított könyvtár. A Vcpkg a CMAKE_TOOLCHAIN_FILE-on keresztül integrálódik a CMake-kel.

A C++ teljesítménye mobil eszközökön

C++ maximális teljesítményt nyújt mobil eszközökön a natív ARM kódba fordításnak és a szemétgyűjtő hiányának köszönhetően. A Google tesztek szerint (Android Performance Patterns, 2024) a JNI kód C++-ban 3–10-szer gyorsabban fut, mint a megfelelő Java kód számításigényes feladatoknál.

A C++ teljesítményének kulcstényezői mobil platformokon: gyorsítótár-lokalitás (adatok folyamatos memóriában való elhelyezése), NEON SIMD utasítások ARM-hez, aszinkron munka JNI-vel üzenetsorokon keresztül. NEON — az ARM SIMD kiterjesztése, amely lehetővé teszi 128 bit adat egyetlen utasításban történő feldolgozását, nélkülözhetetlen audio, video és képfeldolgozáshoz.

cpp
// Tömb SIMD feldolgozása NEON intrinsics segítségével
#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);
    }
}

A vld1q_f32 betölt 4 float-ot a memóriából egy 128 bites NEON regiszterbe. A vmulq_f32 mind a 4 elemet megszorozza 0.5-tel egy ciklusban. A vst1q_f32 visszaírja az eredményt. SIMD nélkül ugyanaz a ciklus 4 szorzást végezne szekvenciálisan — a NEON akár 4x gyorsulást biztosít az ilyen műveletekhez.

MűveletC++ (ms)Java/Kotlin (ms)Gyorsulás
1920x1080 kép feldolgozása12453.75x
Gyors Fourier-transzformáció (FFT)8344.25x
AES-256 titkosítás 1MB blokk3186x
ZLIB adattömörítés5224.4x

Gyakori hibák a C++ mobil projektekben való használatakor

Az első és legveszélyesebb hiba — memóriaszivárgás. Minden new-hoz tartoznia kell egy delete-nek, minden new[]-hoz — delete[]. Korlátozott RAM-mal rendelkező mobileszközökön bármilyen szivárgás OOM-hoz (Out Of Memory) és az alkalmazás összeomlásához vezet. Használjon RAII-t intelligens pointereken keresztül: std::unique_ptr, std::shared_ptr, std::weak_ptr.

A második hiba — az ABI-kompatibilitás figyelmen kívül hagyása. Az armeabi-v7a-ra fordított könyvtár nem töltődik be ARM64 eszközön. Mindig adja meg az abiFilters-t a build.gradle-ben, és teszteljen valódi eszközökön, ne csak az x86_64 emulátoron. Használja az Android App Bundle-t az automatikus ABI szűréshez.

A harmadik gyakori hiba — gyakori JNI hívások. Minden Java és C++ közötti átmenet körülbelül 50–100 ns-ba kerül. Ha egy 10000 elemből álló tömböt egyesével dolgoz fel JNI-n keresztül, az overhead meghaladja a hasznos munkát. Az adatokat teljes tömbökként továbbítsa, és a C++ oldalon dolgozza fel.

Többszálúsági problémák — egy másik gyakori hiba. A C++ elindíthat std::thread-et, de a JNI-hez csak a Java által létrehozott szálból lehet hozzáférni. Java metódusok C++ szálból való hívásához használja az AttachCurrentThread / DetachCurrentThread függvényeket JNI-n keresztül.

cpp
// Java helyes meghívása C++ szálból
JavaVM *g_vm; // globális pointer, JNI_OnLoad-nál szerezve

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();
    }
}

Gyakran ismételt kérdések

Mi az Android NDK és miért használnak benne C++-t?

Android NDK (Native Development Kit) — eszközkészlet alkalmazások részeinek C vagy C++ nyelven történő írásához. Teljesítménykritikus feladatokhoz, C/C++ könyvtárak Androidra portolásához és a Unity és Unreal Engine keresztplatformos kódjának megvalósításához használják.

Milyen Unity játékokat írnak C++-ban?

A Unity-ben a játéklogika kódját C#-ban írják, de a C++-t az Android NDK-val együtt használják bővítményekhez, hardveres gyorsítással való munkához, saját C++ könyvtárak portolásához és natív SDK-k integrálásához hirdetésekhez és analitikához.

Hogyan kell konfigurálni a CMakeLists.txt-t C++-hoz Androidon?

CMakeLists.txt leírja a forrásfájlokat, könyvtárakat és fordítási kapcsolókat. A minimális konfiguráció tartalmazza az add_library-t a .so buildeléséhez és a target_link_libraries-t az Android log és más rendszerkönyvtárak csatlakoztatásához.

A JNI C++-ban kötelező Androidon?

JNI (Java Native Interface) — a réteg az Android alkalmazás Java/Kotlin kódja és a C++ könyvtár között. Ha a C++-t Java-ból hívják, a JNI kötelező. Lehet C++ kódot teljes egészében NDK-n keresztül írni, de a belépési pont általában egy Java activity, amely natív függvényeket hív meg.

Mikor indokolt a C++ a Kotlin helyett a mobilfejlesztésben?

C++ indokolt játékokhoz, valós idejű hang/videó feldolgozáshoz, számítógépes látáshoz, kriptográfiához, fizikai szimulációkhoz és könyvtárak más platformokról való portolásához. Egy átlagos UI alkalmazáshoz a Kotlin hatékonyabb és egyszerűbb.

Összefoglalás

  • C++ — többparadigmás nyelv kézi memóriakezeléssel, használata Android NDK-ban, Unity-ben és Unreal Engine-ben nagy teljesítményű kódhoz
  • Android NDK C++-t .so könyvtárakká fordítja ARM architektúrákhoz a Clang toolchain-nel LLVM-ből
  • Unreal Engine teljesen C++-ra épül UHT reflexiós rendszerrel, a Unity C++-t használ a renderelési és fizikai magban
  • JNI — kötelező híd a Java/Kotlin és C++ között Androidon a Java___ elnevezési konvencióval
  • CMake — a fő build rendszer C++-hoz az NDK-ban, támogatja a C++20-at és a Gradle integrációt
  • NEON SIMD akár 4x gyorsulást biztosít az adatfeldolgozásban ARM processzorokon 128 bites vektorutasításokon keresztül
  • Gyakori hibák: memóriaszivárgás, helytelen ABI az abiFilters-ben, gyakori JNI hívások és többszálúság AttachCurrentThread nélkül

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is