C++ у мобилном развоју: Android NDK, Unity и Unreal Engine

Аутор: IT Sectr Објављено: 2026-02-10 Време читања: 11 мин

C++ — вишенамјенски програмски језик са ручним управљањем меморијом, који комбинује процедурално, објектно-оријентисано и генеричко програмирање. У мобилном развоју, C++ се користи кроз Android NDK за преношење библиотека и кроз гејм енџине Unity и Unreal Engine за креирање крос-платформских игара. Према TIOBE (2026), C++ је међу топ 5 језика по популарности међу професионалним програмерима.

Главне тачке

  • C++ — језик системског програмирања који се користи у Android NDK, Unity и Unreal Engine
  • Android NDK омогућава компилацију C++ кода у изворне .so библиотеке за ARM процесоре
  • Unreal Engine је у потпуности изграђен на C++-у, а Unity користи C++ за нисконвојске додатке
  • JNI (Java Native Interface) — мост између Java/Kotlin и C++-а на Android-у
  • CMake и NDK Build — системи за изградњу C++ пројеката за мобилне платформе

Шта је C++?

C++ — програмски језик који је створио Бјарне Страуструп 1985. године као проширење језика C са подршком за класе. C++ пружа директан приступ меморији кроз показиваче, шаблонско метапрограмирање и вишеструко насљеђивање. Стандарди C++17 и C++20 додали су корутине, концепте и ranges.

За разлику од Java и Kotlin, C++ нема сакупљач смећа — програмер ручно управља алокацијом и ослобађањем меморије кроз операторе new и delete. Ово пружа потпуну контролу над перформансама, али захтијева дисциплину. Према JetBrains Developer Survey (2025), 42% C++ програмера користи језик у индустрији игара.

Стандарди C++-а еволуирају сваке три године: C++11 (ламбде, auto, unique_ptr), C++14 (генерализоване ламбде), C++17 (if constexpr, filesystem), C++20 (модули, корутине, концепти). Компилатори Clang и GCC подржавају све актуелне стандарде, а за Android NDK се користи Clang из LLVM ланца алата.

Разлике између C++-а и Java и Kotlin

Главна разлика C++ у односу на JVM језике — ручно управљање меморијом и компилација директно у машински код. Java и Kotlin раде на виртуелној машини са аутоматским сакупљачем смећа. C++ код се компилира у изворни бинарни фајл за одређену архитектуру — ARM, x86 или RISC-V.

КритеријумC++Java / Kotlin
Управљање меморијомРучно (new/delete, RAII)Аутоматско (Garbage Collector)
КомпилацијаИзворни машински кодБајт-код JVM / ART
ПерформансеМаксималне (zero-cost abstractions)Високе са GC паузама
Употреба у мобилном развојуNDK, игре, библиотекеUI апликације, бизнис логика
ИзградњаCMake, NDK Build, Gradle + NDKGradle, Maven
Крос-платформска подршкаКомпилација за сваку платформуJVM / ART свуда

C++ у мобилном развоју: Android NDK

Android NDK (Native Development Kit) — Google алат за писање дијелова Android апликације у C и C++. NDK укључује ланац алата заснован на Clang, системске заглавне датотеке Android-а, библиотеке за отклањање грешака и профилисање. Верзија r27 (2025) подржава C++20 и користи LLVM 18.

NDK компилира C++ код у динамичке .so библиотеке за ARM64, ARM32, x86 и x86_64 архитектуре. Java или Kotlin апликација учитава ове библиотеке преко System.loadLibrary() и позива изворне функције преко JNI. Према Google-у, NDK је преузет више од 5 милиона пута.

Структура пројекта са NDK

Типичан пројекат са Android NDK садржи фолдер app/src/main/cpp/ са изворним C++ датотекама, CMakeLists.txt за изградњу и Java класу са декларацијом изворних метода. Gradle повезује NDK кроз блок externalNativeBuild у build.gradle.

cpp
// native-lib.cpp — једноставан JNI метод за 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());
}

Код декларише JNI функцију са пуним именом Java_com_example_app_MainActivity_stringFromJNI — ово је JNI конвенција именовања. Функција прима показивач на JNIEnv (окружење извршења) и jobject (инстанцу класе која позива). env->NewStringUTF ствара Java стринг из C++ стринга.

ABI и циљне архитектуре

Android подржава неколико ABI (Application Binary Interface): arm64-v8a (64-битни ARM уређаји, 99% модерних паметних телефона), armeabi-v7a (32-битни ARM, старији уређаји), x86_64 (емулатори). NDK омогућава изградњу .so за сваку архитектуру кроз ABI филтере у build.gradle.

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

C++ и гејм енџини: Unity и Unreal Engine

C++ — главни језик гејм енџина. Unreal Engine користи C++ за цијели код игре, а Unity користи C++ у језгру енџина за рендеровање и физику. Чак и ако програмер пише у C# у Unity-ју, испод хаубе C++ управља графиком, звуком и физичким прорачунима.

Unreal Engine: C++ као главни језик

Unreal Engine је изграђен на C++ од нуле. Код логике игре се пише у C++ коришћењем макроа UHT (Unreal Header Tool) за интеграцију са Blueprints — визуелним системом скриптовања. Класе насљеђују од базних типова AActor, UObject, UGameInstance са префиксним словима U, A, F.

cpp
// Класа лика у Unreal Engine-у у 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;
};

Макрои UCLASS() и UPROPERTY() — дио система рефлексије Unreal Engine-а. UHT (Unreal Header Tool) генерише C++ код из заглавних датотека за серијализацију, блупринте и мрежну репликацију. MoveSpeed се приказује у едитору кроз UPROPERTY(EditAnywhere).

Unity: C++ у додацима и Native SDK

Unity користи C# за логику игре, али C++ се користи у Native додацима — .so библиотекама за Android и .bundle за iOS. Кроз Android NDK се могу повезати C++ SDK рекламних мрежа, аналитике или портовати C++ библиотека из десктоп игара.

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

У овом примјеру, C# маршалира позив C++ функцији ProcessFrame кроз P/Invoke. Атрибут DllImport одређује име .so библиотеке. C++ функција обрађује кадар у реалном времену и враћа резултат. Овај приступ се користи за пост-ефекте и компјутерски вид.

JNI: интеракција Java и C++

JNI (Java Native Interface) — стандардни механизам за позивање C/C++ кода из Java или Kotlin. На Android-у, JNI је једини начин да се пренесу подаци између виртуелне машине ART и изворне библиотеке. Сваки JNI позив има додатне трошкове, па се подаци преносе у пакетима, а не појединачним пољима.

JNIEnv — показивач на табелу JNI функција. env->FindClass учитава Java класу, env->GetMethodID добија идентификатор метода, env->CallVoidMethod га позива. За стрингове се користи GetStringUTFChars и ReleaseStringUTFChars. JNI такође подржава глобалне и слабе референце на Java објекте.

cpp
// Преношење низа бајтова из C++ у Java кроз 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; // инвертујемо бајтове
    }

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

GetByteArrayElements добија показивач на Java бајт низ. JNI_COMMIT у ReleaseByteArrayElements копира промјене назад у Java низ без ослобађања меморије. For петља обрађује на CPU-у са максималним перформансама C++-а без GC пауза.

Управљање меморијом у JNI

Главна опасност JNI — цурење глобалних референци. Сваки NewGlobalRef мора бити ослобођен кроз DeleteGlobalRef. Локалне референце (које враћају FindClass, NewStringUTF) аутоматски се бришу при повратку из изворне функције. За интензивне позиве користите PushLocalFrame / PopLocalFrame.

CMake и системи за изградњу C++-а под Android-ом

CMake — главни алат за изградњу C++-а у Android NDK. CMakeLists.txt описује циљеве изградње, библиотеке и зависности. Gradle позива CMake кроз externalNativeBuild, преносећи путање до NDK и ланца алата. Алтернатива — NDK Build заснован на Android.mk и Application.mk.

CMake 3.22+ подржава пресетове (CMakePresets.json) за различите конфигурације: debug, release, profile са различитим оптимизацијским заставама. За Android се користи ланац алата android.toolchain.cmake из NDK, који Gradle аутоматски замјењује при изградњи.

cmake
# CMakeLists.txt за 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) ствара .so библиотеку. target_link_libraries повезује системске библиотеке android (за JNI) и log (за __android_log_print). Статичка библиотека libjpeg.a се линкује за рад са JPEG сликама. CXX_STANDARD 20 укључује подршку за C++20.

vcpkg и управљање зависностима

vcpkg — менаџер пакета за C++ од Microsoft-а, који подржава Android NDK као циљну платформу. Кроз vcpkg се могу инсталирати Boost, OpenCV, SQLite, nlohmann-json и друге библиотеке компилиране за Android ABI. Vcpkg се интегрише са CMake-ом кроз CMAKE_TOOLCHAIN_FILE.

Перформансе C++-а на мобилним уређајима

C++ пружа максималне перформансе на мобилним уређајима захваљујући компилацији у изворни ARM код и одсуству сакупљача смећа. Према Google тестовима (Android Performance Patterns, 2024), JNI код у C++-у се извршава 3–10 пута брже од еквивалентног Java кода за задатке са интензивним прорачунима.

Кључни фактори перформанси C++-а на мобилним платформама: кеш локалност (смјештање података у континуирану меморију), SIMD NEON инструкције за ARM, асинхрони рад са JNI-јем кроз редове порука. NEON — SIMD проширење ARM-а, које омогућава обраду 128 бита података у једној инструкцији, незамјенљиво за обраду звука, видеа и слика.

cpp
// SIMD обрада низа кроз 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 учитава 4 float-а из меморије у 128-битни NEON регистар. vmulq_f32 множи сва 4 елемента са 0.5 у једном циклусу. vst1q_f32 чува резултат назад. Без SIMD-а, иста петља би извршила 4 множења секвенцијално — NEON даје убрзање до 4x за такве операције.

ОперацијаC++ (ms)Java/Kotlin (ms)Убрзање
Обрада слике 1920x108012453.75x
Брза Фуријеова трансформација (FFT)8344.25x
AES-256 шифровање блока 1MB3186x
ZLIB компресија података5224.4x

Типичне грешке при коришћењу C++-а у мобилним пројектима

Прва и најопаснија грешка — цурење меморије. Сваки new мора имати delete, сваки new[] — delete[]. На мобилним уређајима са ограниченим RAM-ом, било које цурење доводи до OOM (Out Of Memory) и пада апликације. Користите RAII кроз паметне показиваче: std::unique_ptr, std::shared_ptr, std::weak_ptr.

Друга грешка — игнорисање ABI компатибилности. Библиотека компилирана за armeabi-v7a неће се учитати на ARM64 уређају. Увијек наводите abiFilters у build.gradle и тестирајте на стварним уређајима, а не само x86_64 емулатору. Користите Android App Bundle за аутоматско филтрирање ABI-ја.

Трећа типична грешка — чести JNI позиви. Сваки прелаз између Java и C++ кошта око 50–100 нс. Ако обрађујете низ од 10000 елемената један по један кроз JNI, додатни трошак ће надмашити користан рад. Преносите податке као цијеле низове и обрађујте на C++ страни.

Проблеми са вишенитним радом — још једна честа грешка. C++ може покренути std::thread, али приступ JNI-ју је могућ само из нити коју је створила Java. За позивање Java метода из C++ нити користите AttachCurrentThread / DetachCurrentThread кроз JNI.

cpp
// Правилно позивање Java из C++ нити
JavaVM *g_vm; // глобални показивач, добијен при 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();
    }
}

Често постављана питања

Шта је Android NDK и зашто се у њему користи C++?

Android NDK (Native Development Kit) — алат за писање дијелова апликације у C или C++. Користи се за задатке критичне за перформансе, преношење C/C++ библиотека на Android и имплементацију крос-платформског кода Unity и Unreal Engine-а.

Које игре у Unity-ју се пишу у C++?

У Unity-ју код логике игре се пише у C#, али C++ се користи у комбинацији са Android NDK за додатке, рад са хардверским убрзањем, преношење властитих C++ библиотека и интеграцију изворних SDK-ова за огласе и аналитику.

Како подесити CMakeLists.txt за C++ под Android-ом?

CMakeLists.txt описује изворне датотеке, библиотеке и заставе компилације. Минимална конфигурација укључује add_library за изградњу .so и target_link_libraries за повезивање Android log-а и других системских библиотека.

Да ли је JNI у C++ обавезан за Android?

JNI (Java Native Interface) — слој између Java/Kotlin кода Android апликације и C++ библиотеке. Ако се C++ позива из Java, JNI је обавезан. Можете писати C++ код у потпуности кроз NDK, али улазна тачка је обично Java активност која позива изворне функције.

Када је C++ оправдан умјесто Kotlin-а у мобилном развоју?

C++ је оправдан за игре, обраду звука/видеа у реалном времену, компјутерски вид, криптографију, физичке симулације и преношење библиотека са других платформи. За обичну UI апликацију, Kotlin је ефикаснији и једноставнији.

Резиме

  • C++ — вишенамјенски језик са ручним управљањем меморијом, који се користи у Android NDK, Unity и Unreal Engine за код високих перформанси
  • Android NDK компилира C++ у .so библиотеке за ARM архитектуре са Clang ланцем алата из LLVM
  • Unreal Engine је у потпуности изграђен на C++-у са UHT системом рефлексије, Unity користи C++ у језгру рендеровања и физике
  • JNI — обавезан мост између Java/Kotlin и C++-а на Android-у са конвенцијом именовања Java_<пакет>_<класа>_<метод>
  • CMake — главни систем изградње за C++ у NDK, подржава C++20 и интеграцију са Gradle-ом
  • NEON SIMD обезбјеђује до 4x убрзања обраде података на ARM процесорима кроз 128-битне векторске инструкције
  • Типичне грешке: цурење меморије, погрешан ABI у abiFilters, чести JNI позиви и вишенитни рад без AttachCurrentThread

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође