Mobil geliştirmede C++: Android NDK, Unity ve Unreal Engine

Yazar: IT Sectr Yayınlanma: 2026-02-10 Okuma süresi: 11 dk

C++, manuel bellek yönetimine sahip, prosedürel, nesne yönelimli ve genel programlamayı birleştiren çok paradigmalı bir programlama dilidir. Mobil geliştirmede C++, Android NDK aracılığıyla kütüphaneleri taşımak ve Unity ile Unreal Engine oyun motorları aracılığıyla çapraz platform oyunlar oluşturmak için kullanılır. TIOBE (2026)'ya göre C++, profesyonel geliştiriciler arasında en popüler 5 dil arasında yer almaktadır.

Önemli Noktalar

C++ nedir?

C++, 1985 yılında Bjarne Stroustrup tarafından C dilinin sınıf desteğiyle genişletilmesi olarak oluşturulmuş bir programlama dilidir. C++, işaretçiler aracılığıyla doğrudan bellek erişimi, şablon meta programlama ve çoklu kalıtım sağlar. C++17 ve C++20 standartları, coroutine, concept ve range eklemiştir.

Java ve Kotlin'in aksine, C++'da çöp toplayıcı yoktur — geliştirici, new ve delete operatörleri aracılığıyla belleği manuel olarak yönetir. Bu, performans üzerinde tam kontrol sağlar ancak disiplin gerektirir. JetBrains Developer Survey (2025)'e göre, C++ geliştiricilerinin %42'si dili oyun endüstrisinde kullanmaktadır.

C++ standartları her üç yılda bir gelişir: C++11 (lambda, auto, unique_ptr), C++14 (genel lambda), C++17 (if constexpr, filesystem), C++20 (modüller, coroutine, concept). Clang ve GCC derleyicileri tüm güncel standartları destekler ve Android NDK, LLVM araç zincirinden Clang kullanır.

C++ ve Java/Kotlin arasındaki farklar

C++ ve JVM dilleri arasındaki temel fark, manuel bellek yönetimi ve doğrudan makine koduna derlemedir. Java ve Kotlin, otomatik çöp toplama ile sanal makine üzerinde çalışır. C++ kodu, belirli bir mimari için — ARM, x86 veya RISC-V — yerel ikili dosyaya derlenir.

KriterC++Java / Kotlin
Bellek yönetimiManuel (new/delete, RAII)Otomatik (Çöp toplayıcı)
DerlemeYerel makine koduJVM / ART bayt kodu
PerformansMaksimum (sıfır maliyetli soyutlamalar)GC duraklamaları ile yüksek
Mobil geliştirmede kullanımNDK, oyunlar, kütüphanelerUI uygulamaları, iş mantığı
DerlemeCMake, NDK Build, Gradle + NDKGradle, Maven
Çapraz platformHer platform için derlemeHer yerde JVM / ART

Mobil geliştirmede C++: Android NDK

Android NDK (Native Development Kit), Android uygulamalarının parçalarını C ve C++ ile yazmak için Google'ın araç takımıdır. NDK, Clang tabanlı bir araç zinciri, Android sistem başlık dosyaları ve hata ayıklama ve profilleme kütüphaneleri içerir. Sürüm r27 (2025) C++20'yi destekler ve LLVM 18 kullanır.

NDK, C++ kodunu ARM64, ARM32, x86 ve x86_64 mimarileri için dinamik .so kütüphanelerine derler. Bir Java veya Kotlin uygulaması, bu kütüphaneleri System.loadLibrary() aracılığıyla yükler ve JNI aracılığıyla yerel işlevleri çağırır. Google'a göre NDK, 5 milyondan fazla kez indirilmiştir.

NDK ile proje yapısı

Tipik bir Android NDK projesi, C++ kaynak dosyalarını içeren app/src/main/cpp/ klasörünü, derleme için CMakeLists.txt'yi ve yerel yöntem bildirimlerini içeren bir Java sınıfını içerir. Gradle, build.gradle'daki externalNativeBuild bloğu aracılığıyla NDK'yı bağlar.

cpp
// native-lib.cpp — Android için basit JNI yöntemi
#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());
}

Kod, Java_com_example_app_MainActivity_stringFromJNI tam adıyla bir JNI işlevi bildirir — bu JNI adlandırma kuralıdır. İşlev, JNIEnv (yürütme ortamı) ve jobject (çağıran sınıf örneği) için bir işaretçi alır. env->NewStringUTF, C++ dizesinden bir Java dizesi oluşturur.

ABI ve hedef mimariler

Android, birden çok ABI (Uygulama İkili Arayüzü) destekler: arm64-v8a (64-bit ARM cihazlar, modern akıllı telefonların %99'u), armeabi-v7a (32-bit ARM, eski cihazlar), x86_64 (emülatörler). NDK, build.gradle'daki ABI filtreleri aracılığıyla her mimari için .so derlemeye olanak tanır.

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

C++ ve oyun motorları: Unity ve Unreal Engine

C++, oyun motorlarının birincil dilidir. Unreal Engine, tüm oyun kodu için C++ kullanırken, Unity, işleme ve fizik için motor çekirdeğinde C++ kullanır. Bir geliştirici Unity'de C# ile yazsa bile, perde arkasında C++ grafikleri, sesi ve fizik hesaplamalarını yönetir.

Unreal Engine: Ana dil olarak C++

Unreal Engine, sıfırdan C++ üzerine inşa edilmiştir. Oyun mantığı kodu, Blueprints (görsel betik sistemi) ile entegrasyon için UHT (Unreal Header Tool) makroları kullanılarak C++ ile yazılır. Sınıflar, U, A, F önek harfleriyle AActor, UObject, UGameInstance temel türlerinden kalıtım alır.

cpp
// Unreal Engine'de C++ kullanarak karakter sınıfı
#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() ve UPROPERTY() makroları, Unreal Engine yansıma sisteminin bir parçasıdır. UHT (Unreal Header Tool), serileştirme, blueprintler ve ağ çoğaltma için başlık dosyalarından C++ kodu oluşturur. MoveSpeed, UPROPERTY(EditAnywhere) aracılığıyla düzenleyicide görüntülenir.

Unity: Eklentilerde ve yerel SDK'da C++

Unity, oyun mantığı için C# kullanır, ancak C++, yerel eklentilerde — Android için .so kütüphaneleri ve iOS için .bundle — kullanılır. Android NDK aracılığıyla, reklam ağları, analitik için C++ SDK'ları entegre edilebilir veya masaüstü oyunlarından C++ kütüphaneleri taşınabilir.

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

Bu örnekte, C#, P/Invoke aracılığıyla C++ ProcessFrame işlevine bir çağrıyı marshallar. DllImport özniteliği, .so kütüphanesinin adını belirtir. C++ işlevi, gerçek zamanlı olarak kareyi işler ve sonucu döndürür. Bu yaklaşım, son efektler ve bilgisayarlı görü için kullanılır.

JNI: Java ve C++ etkileşimi

JNI (Java Native Interface), Java veya Kotlin'den C/C++ kodunu çağırmak için standart mekanizmadır. Android'de JNI, ART sanal makinesi ile yerel kütüphane arasında veri aktarmanın tek yoludur. Her JNI çağrısının ek yükü vardır, bu nedenle veriler birer alan yerine toplu olarak aktarılmalıdır.

JNIEnv, JNI işlev tablosuna bir işaretçidir. env->FindClass bir Java sınıfı yükler, env->GetMethodID bir yöntem tanımlayıcısı alır, env->CallVoidMethod onu çağırır. Dizeler için GetStringUTFChars ve ReleaseStringUTFChars kullanılır. JNI ayrıca Java nesnelerine genel ve zayıf referansları da destekler.

cpp
// JNI aracılığıyla C++'tan Java'ya bayt dizisi aktarma
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; // baytları ters çevir
    }

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

GetByteArrayElements, Java bayt dizisine bir işaretçi alır. ReleaseByteArrayElements'teki JNI_COMMIT, belleği serbest bırakmadan değişiklikleri Java dizisine geri kopyalar. For döngüsü işlemesi, GC duraklamaları olmadan maksimum C++ performansıyla CPU'da çalışır.

JNI'de bellek yönetimi

JNI'nin ana tehlikesi, genel referans sızıntılarıdır. Her NewGlobalRef, DeleteGlobalRef aracılığıyla serbest bırakılmalıdır. Yerel referanslar (FindClass, NewStringUTF tarafından döndürülen), yerel işlevden dönüşte otomatik olarak serbest bırakılır. Yoğun çağrılar için PushLocalFrame / PopLocalFrame kullanın.

Android'de C++ için CMake ve derleme sistemleri

CMake, Android NDK'da C++ için birincil derleme aracıdır. CMakeLists.txt, derleme hedeflerini, kütüphaneleri ve bağımlılıkları tanımlar. Gradle, externalNativeBuild aracılığıyla CMake'i çağırır ve NDK ile araç zincirine yolları iletir. Bir alternatif, Android.mk ve Application.mk tabanlı NDK Build'dir.

CMake 3.22+, farklı optimizasyon bayraklarına sahip farklı yapılandırmalar (debug, release, profile) için ön ayarları (CMakePresets.json) destekler. Android için, NDK'dan android.toolchain.cmake araç zinciri kullanılır ve derleme sırasında Gradle tarafından otomatik olarak sağlanır.

cmake
# Android NDK projesi için CMakeLists.txt
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) bir .so kütüphanesi oluşturur. target_link_libraries, android (JNI için) ve log (__android_log_print için) sistem kütüphanelerini bağlar. Statik kütüphane libjpeg.a, JPEG görüntü işleme için bağlanır. CXX_STANDARD 20, C++20 desteğini etkinleştirir.

vcpkg ve bağımlılık yönetimi

vcpkg, Android NDK'yı hedef platform olarak destekleyen Microsoft'un C++ paket yöneticisidir. vcpkg aracılığıyla, Android ABI için derlenmiş Boost, OpenCV, SQLite, nlohmann-json ve diğer kütüphaneler kurulabilir. Vcpkg, CMAKE_TOOLCHAIN_FILE aracılığıyla CMake ile entegre olur.

Mobil cihazlarda C++ performansı

C++, yerel ARM koduna derleme ve çöp toplayıcının olmaması sayesinde mobil cihazlarda maksimum performans sağlar. Google testlerine göre (Android Performance Patterns, 2024), C++'daki JNI kodu, hesaplama yoğun görevler için eşdeğer Java kodundan 3–10 kat daha hızlı çalışır.

Mobil platformlarda C++ performansının temel faktörleri: önbellek yerelliği (bitişik bellek düzeni), ARM için NEON SIMD talimatları, mesaj kuyrukları aracılığıyla eşzamansız JNI iletişimi. NEON, ARM'nin SIMD uzantısıdır, tek bir talimatta 128 bit veri işler ve ses, video ve görüntü işleme için vazgeçilmezdir.

cpp
// NEON intrinsics ile SIMD dizi işleme
#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, bellekten 128-bit NEON yazmacına 4 float yükler. vmulq_f32, tüm 4 öğeyi bir döngüde 0.5 ile çarpar. vst1q_f32, sonucu geri kaydeder. SIMD olmadan, aynı döngü sırayla 4 çarpma yapardı — NEON, bu tür işlemler için 4x'e kadar hızlanma sağlar.

İşlemC++ (ms)Java/Kotlin (ms)Hızlanma
1920x1080 görüntü işleme12453.75x
Hızlı Fourier Dönüşümü (FFT)8344.25x
1MB blok AES-256 şifreleme3186x
ZLIB veri sıkıştırma5224.4x

Mobil projelerde C++ kullanırken yaygın hatalar

İlk ve en tehlikeli hata bellek sızıntılarıdır. Her new'in bir delete'i, her new[]'in bir delete[]'i olmalıdır. Sınırlı RAM'e sahip mobil cihazlarda, herhangi bir sızıntı OOM (Bellek Yetersiz) ve uygulama çökmesine yol açar. Akıllı işaretçiler (std::unique_ptr, std::shared_ptr, std::weak_ptr) aracılığıyla RAII kullanın.

İkinci hata, ABI uyumluluğunu göz ardı etmektir. armeabi-v7a için derlenmiş bir kütüphane, ARM64 cihazda yüklenmez. build.gradle'da her zaman abiFilters belirtin ve yalnızca x86_64 emülatöründe değil, gerçek cihazlarda test edin. Otomatik ABI filtrelemesi için Android App Bundle kullanın.

Üçüncü yaygın hata, sık JNI çağrılarıdır. Java ve C++ arasındaki her geçiş yaklaşık 50–100 ns tutar. JNI aracılığıyla 10000 öğelik bir diziyi tek tek işlerseniz, ek yük faydalı işi aşar. Dizilerin tamamını bir kerede geçirin ve C++ tarafında işleyin.

Çoklu iş parçacığı sorunları başka bir yaygın hatadır. C++, std::thread başlatabilir, ancak JNI'ye yalnızca Java tarafından oluşturulan iş parçacıklarından erişilebilir. Bir C++ iş parçacığından Java yöntemlerini çağırmak için JNI aracılığıyla AttachCurrentThread / DetachCurrentThread kullanın.

cpp
// C++ iş parçacığından Java'yı doğru şekilde çağırma
JavaVM *g_vm; // JNI_OnLoad'da alınan genel işaretçi

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

Sıkça Sorulan Sorular

Android NDK nedir ve neden C++ gereklidir?

Android NDK (Native Development Kit), uygulamaların parçalarını C veya C++ ile yazmak için bir araç takımıdır. Performans açısından kritik görevler, C/C++ kütüphanelerini Android'e taşıma ve Unity ile Unreal Engine için çapraz platform kodu uygulamada kullanılır.

Unity'nin hangi oyunları C++ ile yazılır?

Unity'de oyun mantığı kodu C# ile yazılır, ancak C++, Android NDK ile birlikte eklentiler, donanım hızlandırma, özel C++ kütüphanelerini taşıma ve reklam ve analitik için yerel SDK'ları entegre etmek için kullanılır.

Android'de C++ için CMakeLists.txt nasıl yapılandırılır?

CMakeLists.txt, kaynak dosyaları, kütüphaneleri ve derleme bayraklarını tanımlar. Minimum yapılandırma, .so derlemek için add_library ve Android log ve diğer sistem kütüphanelerini bağlamak için target_link_libraries içerir.

Android için C++'da JNI zorunlu mu?

JNI (Java Native Interface), bir Android uygulamasının Java/Kotlin kodu ile C++ kütüphanesi arasındaki katmandır. C++ Java'dan çağrılıyorsa JNI zorunludur. NDK aracılığıyla tamamen C++ kodu yazabilirsiniz, ancak giriş noktası genellikle yerel işlevleri çağıran bir Java Activity'dir.

Mobil geliştirmede Kotlin yerine C++ ne zaman haklı çıkar?

C++, oyunlar, gerçek zamanlı ses/video işleme, bilgisayarlı görü, kriptografi, fizik simülasyonları ve diğer platformlardan kütüphaneleri taşımak için haklı çıkar. Sıradan bir UI uygulaması için Kotlin daha verimli ve basittir.

Özet

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun