C++ es un lenguaje de programación multiparadigma con gestión manual de memoria, que combina programación procedural, orientada a objetos y genérica. En el desarrollo móvil, C++ se utiliza a través de Android NDK para portar bibliotecas y mediante los motores de juegos Unity y Unreal Engine para crear juegos multiplataforma. Según TIOBE (2026), C++ se encuentra entre los 5 lenguajes más populares entre los desarrolladores profesionales.
Puntos clave
C++ es un lenguaje de programación creado por Bjarne Stroustrup en 1985 como una extensión del lenguaje C con soporte de clases. C++ proporciona acceso directo a la memoria a través de punteros, metaprogramación de plantillas y herencia múltiple. Los estándares C++17 y C++20 agregaron corrutinas, conceptos y ranges.
A diferencia de Java y Kotlin, C++ no tiene recolector de basura — el desarrollador gestiona manualmente la asignación y liberación de memoria mediante los operadores new y delete. Esto proporciona control total sobre el rendimiento pero requiere disciplina. Según la Encuesta de Desarrolladores de JetBrains (2025), el 42% de los desarrolladores de C++ usan el lenguaje en la industria de los videojuegos.
Los estándares de C++ evolucionan cada tres años: C++11 (lambdas, auto, unique_ptr), C++14 (lambdas genéricas), C++17 (if constexpr, filesystem), C++20 (módulos, corrutinas, conceptos). Los compiladores Clang y GCC soportan todos los estándares actuales, y Android NDK usa Clang del toolchain LLVM.
La principal diferencia entre C++ y los lenguajes JVM es la gestión manual de memoria y la compilación directa a código máquina. Java y Kotlin funcionan sobre una máquina virtual con recolección automática de basura. El código C++ se compila en un binario nativo para una arquitectura específica — ARM, x86 o RISC-V.
| Criterio | C++ | Java / Kotlin |
|---|---|---|
| Gestión de memoria | Manual (new/delete, RAII) | Automática (recolector de basura) |
| Compilación | Código máquina nativo | Bytecode JVM / ART |
| Rendimiento | Máximo (zero-cost abstractions) | Alto con pausas de GC |
| Uso en desarrollo móvil | NDK, juegos, bibliotecas | Aplicaciones UI, lógica de negocio |
| Compilación | CMake, NDK Build, Gradle + NDK | Gradle, Maven |
| Multiplataforma | Compilar para cada plataforma | JVM / ART en todas partes |
Android NDK (Native Development Kit) es un conjunto de herramientas de Google para escribir partes de aplicaciones Android en C y C++. El NDK incluye un toolchain basado en Clang, archivos de cabecera del sistema Android y bibliotecas de depuración y perfilado. La versión r27 (2025) soporta C++20 y usa LLVM 18.
El NDK compila código C++ en bibliotecas dinámicas .so para las arquitecturas ARM64, ARM32, x86 y x86_64. Una aplicación en Java o Kotlin carga estas bibliotecas mediante System.loadLibrary() y llama a funciones nativas a través de JNI. Según Google, el NDK se ha descargado más de 5 millones de veces.
Un proyecto típico con Android NDK contiene la carpeta app/src/main/cpp/ con archivos fuente C++, CMakeLists.txt para la compilación y una clase Java con declaración de métodos nativos. Gradle conecta el NDK mediante el bloque externalNativeBuild en build.gradle.
// native-lib.cpp — método JNI simple para 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());
}El código declara una función JNI con el nombre completo Java_com_example_app_MainActivity_stringFromJNI — esta es la convención de nomenclatura de JNI. La función recibe un puntero a JNIEnv (el entorno de ejecución) y jobject (la instancia de la clase que llama). env->NewStringUTF crea una cadena Java a partir de una cadena C++.
Android soporta varios ABI (Application Binary Interface): arm64-v8a (dispositivos ARM de 64 bits, 99% de los smartphones modernos), armeabi-v7a (ARM de 32 bits, dispositivos antiguos), x86_64 (emuladores). El NDK permite compilar .so para cada arquitectura mediante filtros ABI en build.gradle.
android {
defaultConfig {
ndk {
abiFilters "arm64-v8a", "armeabi-v7a"
}
}
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
version "3.22.1"
}
}
}C++ es el lenguaje principal de los motores de juegos. Unreal Engine usa C++ para todo el código del juego, mientras que Unity utiliza C++ en el núcleo del motor para renderizado y física. Incluso si un desarrollador escribe en C# en Unity, bajo el capó C++ gestiona los gráficos, el sonido y los cálculos físicos.
Unreal Engine está construido sobre C++ desde cero. El código de la lógica del juego se escribe en C++ utilizando macros UHT (Unreal Header Tool) para la integración con Blueprints — un sistema de scripting visual. Las clases heredan de tipos base AActor, UObject, UGameInstance con letras de prefijo U, A, F.
// Clase de personaje en Unreal Engine usando 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;
};Las macros UCLASS() y UPROPERTY() son parte del sistema de reflexión de Unreal Engine. UHT (Unreal Header Tool) genera código C++ a partir de archivos de cabecera para serialización, blueprints y replicación de red. MoveSpeed se muestra en el editor mediante UPROPERTY(EditAnywhere).
Unity usa C# para la lógica del juego, pero C++ se utiliza en Native Plugins — bibliotecas .so para Android y .bundle para iOS. A través de Android NDK se pueden conectar SDK de C++ para redes publicitarias, analítica o portar bibliotecas C++ de juegos de escritorio.
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);
}
}En este ejemplo, C# organiza una llamada a la función C++ ProcessFrame mediante P/Invoke. El atributo DllImport especifica el nombre de la biblioteca .so. La función C++ procesa el fotograma en tiempo real y devuelve el resultado. Este enfoque se utiliza para post-efectos y visión artificial.
JNI (Java Native Interface) es el mecanismo estándar para llamar código C/C++ desde Java o Kotlin. En Android, JNI es la única forma de transferir datos entre la máquina virtual ART y una biblioteca nativa. Cada llamada JNI tiene sobrecarga, por lo que los datos deben transferirse en lotes en lugar de un campo a la vez.
JNIEnv es un puntero a la tabla de funciones JNI. env->FindClass carga una clase Java, env->GetMethodID obtiene un identificador de método, env->CallVoidMethod lo invoca. Para cadenas se usa GetStringUTFChars y ReleaseStringUTFChars. JNI también soporta referencias globales y débiles a objetos Java.
// Pasar array de bytes de C++ a Java mediante 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; // invertir bytes
}
env->ReleaseByteArrayElements(input, buffer, JNI_COMMIT);
}GetByteArrayElements obtiene un puntero al array de bytes Java. JNI_COMMIT en ReleaseByteArrayElements copia los cambios de vuelta al array Java sin liberar memoria. El procesamiento del bucle for se ejecuta en la CPU con el máximo rendimiento de C++ sin pausas de GC.
El principal peligro de JNI son las fugas de referencias globales. Cada NewGlobalRef debe liberarse mediante DeleteGlobalRef. Las referencias locales (devueltas por FindClass, NewStringUTF) se liberan automáticamente al volver de la función nativa. Para llamadas intensivas, use PushLocalFrame / PopLocalFrame.
CMake es la herramienta de compilación principal para C++ en Android NDK. CMakeLists.txt describe los objetivos de compilación, bibliotecas y dependencias. Gradle invoca CMake a través de externalNativeBuild, pasando las rutas al NDK y al toolchain. Una alternativa es NDK Build basado en Android.mk y Application.mk.
CMake 3.22+ soporta presets (CMakePresets.json) para diferentes configuraciones: debug, release, profile con diferentes banderas de optimización. Para Android se usa el toolchain android.toolchain.cmake del NDK, suministrado automáticamente por Gradle durante la compilación.
# CMakeLists.txt para proyecto 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) crea una biblioteca .so. target_link_libraries enlaza las bibliotecas del sistema android (para JNI) y log (para __android_log_print). La biblioteca estática libjpeg.a se enlaza para trabajar con imágenes JPEG. CXX_STANDARD 20 habilita el soporte de C++20.
vcpkg es un gestor de paquetes para C++ de Microsoft que soporta Android NDK como plataforma objetivo. A través de vcpkg se pueden instalar Boost, OpenCV, SQLite, nlohmann-json y otras bibliotecas compiladas para Android ABI. Vcpkg se integra con CMake mediante CMAKE_TOOLCHAIN_FILE.
C++ ofrece el máximo rendimiento en dispositivos móviles gracias a la compilación en código ARM nativo y la ausencia de recolector de basura. Según las pruebas de Google (Android Performance Patterns, 2024), el código JNI en C++ se ejecuta de 3 a 10 veces más rápido que el código Java equivalente para tareas con cálculos intensivos.
Factores clave del rendimiento de C++ en plataformas móviles: localidad de caché (disposición contigua de memoria), instrucciones SIMD NEON para ARM, comunicación JNI asíncrona mediante colas de mensajes. NEON es la extensión SIMD de ARM que procesa 128 bits de datos en una sola instrucción, indispensable para el procesamiento de audio, video e imágenes.
// Procesamiento SIMD de array mediante 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 carga 4 floats de la memoria en un registro NEON de 128 bits. vmulq_f32 multiplica los 4 elementos por 0.5 en un ciclo. vst1q_f32 guarda el resultado de vuelta. Sin SIMD, el mismo bucle realizaría 4 multiplicaciones secuencialmente — NEON proporciona hasta 4x de aceleración para estas operaciones.
| Operación | C++ (ms) | Java/Kotlin (ms) | Aceleración |
|---|---|---|---|
| Procesamiento de imagen 1920x1080 | 12 | 45 | 3.75x |
| Transformada Rápida de Fourier (FFT) | 8 | 34 | 4.25x |
| Cifrado AES-256 de bloque de 1MB | 3 | 18 | 6x |
| Compresión de datos ZLIB | 5 | 22 | 4.4x |
El primer error y el más peligroso son las fugas de memoria. Cada new debe tener un delete, cada new[] debe tener un delete[]. En dispositivos móviles con RAM limitada, cualquier fuga provoca OOM (Out Of Memory) y el cierre de la aplicación. Use RAII mediante punteros inteligentes: std::unique_ptr, std::shared_ptr, std::weak_ptr.
El segundo error es ignorar la compatibilidad ABI. Una biblioteca compilada para armeabi-v7a no se cargará en un dispositivo ARM64. Siempre especifique abiFilters en build.gradle y pruebe en dispositivos reales, no solo en el emulador x86_64. Use Android App Bundle para el filtrado automático de ABI.
El tercer error típico son las llamadas JNI frecuentes. Cada transición entre Java y C++ cuesta entre 50 y 100 ns. Si procesa un array de 10000 elementos uno por uno a través de JNI, la sobrecarga supera el trabajo útil. Pase arrays completos de una vez y procéselos en el lado de C++.
Problemas de concurrencia son otro error frecuente. C++ puede lanzar std::thread, pero solo se puede acceder a JNI desde hilos creados por Java. Para llamar métodos Java desde un hilo de C++, use AttachCurrentThread / DetachCurrentThread a través de JNI.
// Llamar correctamente a Java desde un hilo de C++
JavaVM *g_vm; // puntero global obtenido en 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();
}
}Preguntas frecuentes
Android NDK (Native Development Kit) es un conjunto de herramientas para escribir partes de aplicaciones en C o C++. Se utiliza para tareas críticas de rendimiento, portar bibliotecas C/C++ a Android e implementar código multiplataforma para Unity y Unreal Engine.
En Unity, el código de la lógica del juego se escribe en C#, pero C++ se usa junto con Android NDK para plugins, aceleración hardware, portar bibliotecas C++ propias e integrar SDK nativos para publicidad y analítica.
CMakeLists.txt describe archivos fuente, bibliotecas y banderas de compilación. La configuración mínima incluye add_library para compilar .so y target_link_libraries para enlazar el log de Android y otras bibliotecas del sistema.
JNI (Java Native Interface) es la capa entre el código Java/Kotlin de una aplicación Android y la biblioteca C++. Si se llama C++ desde Java, JNI es obligatorio. Se puede escribir código C++ completamente a través de NDK, pero el punto de entrada suele ser una Activity de Java que llama a funciones nativas.
C++ está justificado para juegos, procesamiento de audio/video en tiempo real, visión artificial, criptografía, simulaciones físicas y portar bibliotecas de otras plataformas. Para una aplicación UI normal, Kotlin es más eficiente y sencillo.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.