C++ inom mobilutveckling: Android NDK, Unity och Unreal Engine

Författare: IT Sectr Publicerad: 2026-02-10 Lästid: 11 min

C++ — ett flerparadigmsprogrammeringsspråk med manuell minneshantering som kombinerar procedur-, objektorienterad och generisk programmering. Inom mobilutveckling används C++ via Android NDK för att portera bibliotek och via spelmotorerna Unity och Unreal Engine för att skapa plattformsoberoende spel. Enligt TIOBE (2026) ligger C++ bland topp 5 språk i popularitet bland professionella utvecklare.

Huvudpunkter

  • C++ — ett systemprogrammeringsspråk som används i Android NDK, Unity och Unreal Engine
  • Android NDK gör det möjligt att kompilera C++-kod till ursprungliga .so-bibliotek för ARM-processorer
  • Unreal Engine är helt byggt på C++, och Unity använder C++ för lågnivåpluginmoduler
  • JNI (Java Native Interface) — bryggan mellan Java/Kotlin och C++ på Android
  • CMake och NDK Build — byggsystem för C++-projekt på mobila plattformar

Vad är C++?

C++ — ett programmeringsspråk skapat av Bjarne Stroustrup 1985 som en utökning av C med stöd för klasser. C++ ger direkt åtkomst till minne via pekare, mall-metaprogrammering och multipelt arv. Standarderna C++17 och C++20 lade till korutiner, koncept och ranges.

Till skillnad från Java och Kotlin har C++ ingen garbage collector — utvecklaren hanterar manuellt minnestilldelning och frigöring via operatorerna new och delete. Detta ger full kontroll över prestanda men kräver disciplin. Enligt JetBrains Developer Survey (2025) använder 42% av C++-utvecklarna språket inom spelindustrin.

C++-standarder utvecklas vart tredje år: C++11 (lambda, auto, unique_ptr), C++14 (generaliserade lambda), C++17 (if constexpr, filesystem), C++20 (moduler, korutiner, koncept). Kompilatorerna Clang och GCC stöder alla aktuella standarder, och för Android NDK används Clang från LLVM-verktygskedjan.

Skillnader mellan C++ och Java och Kotlin

Den huvudsakliga skillnaden mellan C++ och JVM-språk — manuell minneshantering och kompilering direkt till maskinkod. Java och Kotlin körs på en virtuell maskin med automatisk garbage collection. C++-kod kompileras till en ursprunglig binärfil för en specifik arkitektur — ARM, x86 eller RISC-V.

KriteriumC++Java / Kotlin
MinneshanteringManuell (new/delete, RAII)Automatisk (Garbage Collector)
KompileringUrsprunglig maskinkodJVM / ART-bytekod
PrestandaMaximal (zero-cost abstractions)Hög med GC-pauser
Användning inom mobilutvecklingNDK, spel, bibliotekUI-applikationer, affärslogik
ByggCMake, NDK Build, Gradle + NDKGradle, Maven
PlattformsoberoendeKompilering för varje plattformJVM / ART överallt

C++ inom mobilutveckling: Android NDK

Android NDK (Native Development Kit) — Googles verktygssats för att skriva delar av Android-applikationer i C och C++. NDK innehåller en verktygskedja baserad på Clang, systemhuvudfiler för Android, bibliotek för felsökning och profilering. Version r27 (2025) stöder C++20 och använder LLVM 18.

NDK kompilerar C++-kod till dynamiska .so-bibliotek för ARM64-, ARM32-, x86- och x86_64-arkitekturer. Java- eller Kotlin-applikationen laddar dessa bibliotek via System.loadLibrary() och anropar ursprungliga funktioner via JNI. Enligt Google har NDK laddats ner mer än 5 miljoner gånger.

Projektstruktur med NDK

Ett typiskt projekt med Android NDK innehåller mappen app/src/main/cpp/ med C++-källfiler, CMakeLists.txt för bygge och en Java-klass med deklaration av ursprungliga metoder. Gradle kopplar NDK via blocket externalNativeBuild i build.gradle.

cpp
// native-lib.cpp — en enkel JNI-metod för 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());
}

Koden deklarerar en JNI-funktion med det fullständiga namnet Java_com_example_app_MainActivity_stringFromJNI — detta är JNI-namngivningskonventionen. Funktionen tar emot en pekare till JNIEnv (exekveringsmiljö) och jobject (instans av den anropande klassen). env->NewStringUTF skapar en Java-sträng från en C++-sträng.

ABI och målarkitekturer

Android stöder flera ABI (Application Binary Interface): arm64-v8a (64-bitars ARM-enheter, 99% av moderna smartphones), armeabi-v7a (32-bitars ARM, äldre enheter), x86_64 (emulatorer). NDK möjliggör bygge av .so för varje arkitektur via ABI-filter i build.gradle.

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

C++ och spelmotorer: Unity och Unreal Engine

C++ — det primära språket för spelmotorer. Unreal Engine använder C++ för all spelkod, och Unity använder C++ i motorns kärna för rendering och fysik. Även om utvecklaren skriver i C# i Unity hanterar C++ under huven grafik, ljud och fysikberäkningar.

Unreal Engine: C++ som primärt språk

Unreal Engine är byggt på C++ från grunden. Spellojikkod skrivs i C++ med makron från UHT (Unreal Header Tool) för integration med Blueprints — ett visuellt skriptsystem. Klasser ärver från bastyperna AActor, UObject, UGameInstance med prefixbokstäverna U, A, F.

cpp
// Karaktärsklass i Unreal Engine i 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;
};

Makrona UCLASS() och UPROPERTY() — en del av Unreal Engines reflektionssystem. UHT (Unreal Header Tool) genererar C++-kod från rubrikfiler för serialisering, blueprints och nätverksreplikering. MoveSpeed visas i editorn via UPROPERTY(EditAnywhere).

Unity: C++ i pluginmoduler och Native SDK

Unity använder C# för spellojik, men C++ används i Native Plugins — .so-bibliotek för Android och .bundle för iOS. Via Android NDK kan C++ SDK för annonsnätverk, analys kopplas in eller ett C++-bibliotek från datorspel porteras.

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

I detta exempel marshallar C# anropet till C++-funktionen ProcessFrame via P/Invoke. Attributet DllImport anger namnet på .so-biblioteket. C++-funktionen bearbetar bildrutan i realtid och returnerar resultatet. Detta tillvägagångssätt används för post-effekter och datorseende.

JNI: interaktion mellan Java och C++

JNI (Java Native Interface) — den standardmekanism för att anropa C/C++-kod från Java eller Kotlin. På Android är JNI det enda sättet att överföra data mellan den virtuella maskinen ART och ett ursprungligt bibliotek. Varje JNI-anrop har overhead, därför överförs data i batcher, inte fält för fält.

JNIEnv — en pekare till JNI-funktionstabellen. env->FindClass laddar en Java-klass, env->GetMethodID hämtar metodidentifieraren, env->CallVoidMethod anropar den. För strängar används GetStringUTFChars och ReleaseStringUTFChars. JNI stöder också globala och svaga referenser till Java-objekt.

cpp
// Överföring av byte-array från C++ till 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; // invertera bytes
    }

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

GetByteArrayElements hämtar en pekare till Java-bytearrayen. JNI_COMMIT i ReleaseByteArrayElements kopierar ändringarna tillbaka till Java-arrayen utan att frigöra minne. For-loop-bearbetning utförs på CPU med maximal C++-prestanda utan GC-pauser.

Minneshantering i JNI

Den största faran med JNI — läckor av globala referenser. Varje NewGlobalRef måste frigöras via DeleteGlobalRef. Lokala referenser (returnerade av FindClass, NewStringUTF) tas automatiskt bort vid återkomst från den ursprungliga funktionen. För intensiva anrop, använd PushLocalFrame / PopLocalFrame.

CMake och byggsystem för C++ på Android

CMake — det primära byggverktyget för C++ i Android NDK. CMakeLists.txt beskriver byggmål, bibliotek och beroenden. Gradle anropar CMake via externalNativeBuild och skickar sökvägar till NDK och verktygskedjan. Alternativ — NDK Build baserat på Android.mk och Application.mk.

CMake 3.22+ stöder förinställningar (CMakePresets.json) för olika konfigurationer: debug, release, profile med olika optimeringsflaggor. För Android används verktygskedjan android.toolchain.cmake från NDK, som automatiskt ersätts av Gradle vid bygge.

cmake
# CMakeLists.txt för Android NDK-projekt
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) skapar ett .so-bibliotek. target_link_libraries kopplar systembiblioteken android (för JNI) och log (för __android_log_print). Det statiska biblioteket libjpeg.a länkas för arbete med JPEG-bilder. CXX_STANDARD 20 aktiverar C++20-stöd.

vcpkg och beroendehantering

vcpkg — pakethanteraren för C++ från Microsoft, som stöder Android NDK som målplattform. Via vcpkg kan Boost, OpenCV, SQLite, nlohmann-json och andra bibliotek kompilerade för Android ABI installeras. Vcpkg integreras med CMake via CMAKE_TOOLCHAIN_FILE.

Prestanda för C++ på mobila enheter

C++ ger maximal prestanda på mobila enheter tack vare kompilering till ursprunglig ARM-kod och frånvaro av garbage collector. Enligt Googles tester (Android Performance Patterns, 2024) exekveras JNI-kod i C++ 3–10 gånger snabbare än motsvarande Java-kod för beräkningsintensiva uppgifter.

Nyckelfaktorer för C++-prestanda på mobila plattformar: cache-lokalitet (placering av data i sammanhängande minne), NEON SIMD-instruktioner för ARM, asynkront arbete med JNI via meddelandeköer. NEON — ARM:s SIMD-utökning som möjliggör bearbetning av 128 bitar data i en enda instruktion, oumbärlig för ljud-, video- och bildbehandling.

cpp
// SIMD-bearbetning av 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 laddar 4 float från minnet till ett 128-bitars NEON-register. vmulq_f32 multiplicerar alla 4 elementen med 0,5 i en cykel. vst1q_f32 sparar resultatet tillbaka. Utan SIMD skulle samma loop utföra 4 multiplikationer sekventiellt — NEON ger upp till 4x acceleration för sådana operationer.

OperationC++ (ms)Java/Kotlin (ms)Acceleration
Bildbehandling 1920x108012453,75x
Snabb Fouriertransform (FFT)8344,25x
AES-256-kryptering av 1MB-block3186x
ZLIB-datakomprimering5224,4x

Typiska misstag vid användning av C++ i mobilprojekt

Det första och farligaste misstaget — minnesläckor. Varje new måste ha en delete, varje new[] — delete[]. På mobila enheter med begränsat RAM leder varje läcka till OOM (Out Of Memory) och applikationskrasch. Använd RAII via smarta pekare: std::unique_ptr, std::shared_ptr, std::weak_ptr.

Det andra misstaget — ignorera ABI-kompatibilitet. Ett bibliotek kompilerat för armeabi-v7a kommer inte att laddas på en ARM64-enhet. Ange alltid abiFilters i build.gradle och testa på verkliga enheter, inte bara x86_64-emulatorn. Använd Android App Bundle för automatisk ABI-filtrering.

Det tredje typiska misstaget — frekventa JNI-anrop. Varje övergång mellan Java och C++ kostar cirka 50–100 ns. Om du bearbetar en array med 10000 element ett och ett via JNI kommer overheaden att överstiga det nyttiga arbetet. Överför data som hela arrayer och bearbeta på C++-sidan.

Problem med flertrådning — ytterligare ett vanligt misstag. C++ kan starta std::thread, men åtkomst till JNI är endast möjlig från en tråd skapad av Java. För att anropa Java-metoder från en C++-tråd, använd AttachCurrentThread / DetachCurrentThread via JNI.

cpp
// Korrekt anrop av Java från C++-tråd
JavaVM *g_vm; // global pekare, erhållen vid 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();
    }
}

Vanliga frågor

Vad är Android NDK och varför används C++ i det?

Android NDK (Native Development Kit) — en verktygssats för att skriva delar av applikationen i C eller C++. Det används för prestandakritiska uppgifter, portering av C/C++-bibliotek till Android och implementering av plattformsoberoende kod för Unity och Unreal Engine.

Vilka Unity-spel skrivs i C++?

I Unity skrivs spellojikkod i C#, men C++ används i kombination med Android NDK för pluginmoduler, arbete med hårdvaruacceleration, portering av egna C++-bibliotek och integration av ursprungliga SDK:er för annonsering och analys.

Hur konfigurerar man CMakeLists.txt för C++ på Android?

CMakeLists.txt beskriver källfiler, bibliotek och kompileringsflaggor. Minimal konfiguration inkluderar add_library för att bygga .so och target_link_libraries för att koppla Android log och andra systembibliotek.

Är JNI i C++ obligatoriskt för Android?

JNI (Java Native Interface) — lagret mellan Java/Kotlin-koden i Android-applikationen och C++-biblioteket. Om C++ anropas från Java är JNI obligatoriskt. Man kan skriva C++-kod helt via NDK, men ingångspunkten är vanligtvis en Java-aktivitet som anropar ursprungliga funktioner.

När är C++ motiverat istället för Kotlin inom mobilutveckling?

C++ är motiverat för spel, realtidsljud-/videobearbetning, datorseende, kryptografi, fysiksimuleringar och portering av bibliotek från andra plattformar. För en vanlig UI-applikation är Kotlin effektivare och enklare.

Sammanfattning

  • C++ — ett flerparadigmspråk med manuell minneshantering, som används i Android NDK, Unity och Unreal Engine för högpresterande kod
  • Android NDK kompilerar C++ till .so-bibliotek för ARM-arkitekturer med Clang-verktygskedjan från LLVM
  • Unreal Engine är helt byggt på C++ med UHT-reflektionssystem, Unity använder C++ i renderings- och fysikkärnan
  • JNI — den obligatoriska bryggan mellan Java/Kotlin och C++ på Android med namngivningskonventionen Java___
  • CMake — det primära byggsystemet för C++ i NDK, med stöd för C++20 och Gradle-integration
  • NEON SIMD ger upp till 4x acceleration av databearbetning på ARM-processorer via 128-bitars vektorinstruktioner
  • Typiska misstag: minnesläckor, felaktig ABI i abiFilters, frekventa JNI-anrop och flertrådning utan AttachCurrentThread

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också