C++ เป็นภาษาการเขียนโปรแกรมแบบหลายกระบวนทัศน์ที่มีการจัดการหน่วยความจำด้วยตนเอง ผสมผสานการเขียนโปรแกรมแบบเชิงกระบวนคำสั่ง เชิงวัตถุ และเชิงทั่วไป ในการพัฒนามือถือ C++ ถูกใช้ผ่าน Android NDK สำหรับการพอร์ตไลบรารีและผ่านเอนจินเกม Unity และ Unreal Engine สำหรับสร้างเกมข้ามแพลตฟอร์ม ตามข้อมูลจาก TIOBE (2026) C++ อยู่ใน 5 อันดับภาษาที่ได้รับความนิยมสูงสุดในหมู่นักพัฒนามืออาชีพ
ประเด็นสำคัญ
C++ เป็นภาษาการเขียนโปรแกรมที่สร้างโดย Bjarne Stroustrup ในปี 1985 โดยเป็นส่วนขยายของภาษา C พร้อมการสนับสนุนคลาส C++ ให้การเข้าถึงหน่วยความจำโดยตรงผ่านพอยน์เตอร์, การเขียนโปรแกรมเมตาเทมเพลต และการสืบทอดหลายแบบ มาตรฐาน C++17 และ C++20 เพิ่มคอรูทีน, คอนเซปต์ และเรนจ์
不同于 Java และ Kotlin, C++ ไม่มีตัวเก็บขยะ — นักพัฒนาจัดการการจัดสรรและปล่อยหน่วยความจำด้วยตนเองผ่านโอเปอเรเตอร์ new และ delete ซึ่งให้การควบคุมประสิทธิภาพอย่างสมบูรณ์แต่ต้องมีวินัย ตามแบบสำรวจ JetBrains Developer Survey (2025) นักพัฒนา C++ 42% ใช้ภาษาในอุตสาหกรรมเกม
มาตรฐาน C++ พัฒนาทุกสามปี: C++11 (แลมบ์ดา, auto, unique_ptr), C++14 (แลมบ์ดาทั่วไป), C++17 (if constexpr, filesystem), C++20 (โมดูล, คอรูทีน, คอนเซปต์) คอมไพเลอร์ Clang และ GCC รองรับมาตรฐานปัจจุบันทั้งหมด และ Android NDK ใช้ Clang จากชุดเครื่องมือ LLVM
ความแตกต่างหลักระหว่าง C++ และภาษา JVM คือการจัดการหน่วยความจำด้วยตนเองและการคอมไพล์เป็นโค้ดเครื่องโดยตรง Java และ Kotlin ทำงานบนเครื่องเสมือนที่มีการเก็บขยะอัตโนมัติ โค้ด C++ จะถูกคอมไพล์เป็นไบนารีดั้งเดิมสำหรับสถาปัตยกรรมเฉพาะ — ARM, x86 หรือ RISC-V
| เกณฑ์ | C++ | Java / Kotlin |
|---|---|---|
| การจัดการหน่วยความจำ | ด้วยตนเอง (new/delete, RAII) | อัตโนมัติ (ตัวเก็บขยะ) |
| การคอมไพล์ | โค้ดเครื่องดั้งเดิม | ไบต์โค้ด JVM / ART |
| ประสิทธิภาพ | สูงสุด (zero-cost abstractions) | สูงพร้อมการหยุด GC |
| การใช้ในการพัฒนามือถือ | NDK, เกม, ไลบรารี | แอป UI, ตรรกะทางธุรกิจ |
| บิลด์ | CMake, NDK Build, Gradle + NDK | Gradle, Maven |
| ข้ามแพลตฟอร์ม | คอมไพล์สำหรับแต่ละแพลตฟอร์ม | JVM / ART ทุกที่ |
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 ล้านครั้ง
โปรเจกต์ Android NDK ทั่วไปประกอบด้วยโฟลเดอร์ app/src/main/cpp/ พร้อมไฟล์ต้นฉบับ C++, CMakeLists.txt สำหรับบิลด์ และคลาส Java พร้อมการประกาศเมธอดดั้งเดิม Gradle เชื่อมต่อ NDK ผ่านบล็อก externalNativeBuild ใน build.gradle
// 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++
Android รองรับ ABI (อินเทอร์เฟซไบนารีแอปพลิเคชัน) หลายแบบ: arm64-v8a (อุปกรณ์ ARM 64 บิต, 99% ของสมาร์ทโฟนสมัยใหม่), armeabi-v7a (ARM 32 บิต, อุปกรณ์รุ่นเก่า), x86_64 (อีมูเลเตอร์) NDK อนุญาตให้บิลด์ .so สำหรับแต่ละสถาปัตยกรรมผ่านตัวกรอง ABI ใน build.gradle
android {
defaultConfig {
ndk {
abiFilters "arm64-v8a", "armeabi-v7a"
}
}
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
version "3.22.1"
}
}
}C++ เป็นภาษาหลักของเอนจินเกม Unreal Engine ใช้ C++ สำหรับโค้ดเกมทั้งหมด ในขณะที่ Unity ใช้ C++ ในแกนหลักของเอนจินสำหรับการเรนเดอร์และฟิสิกส์ แม้ว่านักพัฒนาจะเขียนด้วย C# ใน Unity เบื้องหลัง C++ จะจัดการกราฟิก เสียง และการคำนวณฟิสิกส์
Unreal Engine สร้างบน C++ ตั้งแต่เริ่มต้น โค้ดตรรกะเกมเขียนด้วย C++ โดยใช้มาโคร UHT (Unreal Header Tool) สำหรับการรวมกับ Blueprints — ระบบสคริปต์ภาพ คลาสสืบทอดจากประเภทพื้นฐาน AActor, UObject, UGameInstance พร้อมตัวอักษรนำหน้า U, A, F
// คลาสตัวละครใน 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# สำหรับตรรกะเกม แต่ C++ ถูกใช้ในปลั๊กอินดั้งเดิม — ไลบรารี .so สำหรับ Android และ .bundle สำหรับ iOS ผ่าน Android NDK สามารถรวม SDK C++ สำหรับเครือข่ายโฆษณา, การวิเคราะห์ หรือพอร์ตไลบรารี C++ จากเกมเดสก์ท็อป
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 Native Interface) เป็นกลไกมาตรฐานสำหรับเรียกโค้ด C/C++ จาก Java หรือ Kotlin ใน Android JNI เป็นวิธีเดียวในการถ่ายโอนข้อมูลระหว่างเครื่องเสมือน ART และไลบรารีดั้งเดิม การเรียก JNI แต่ละครั้งมีค่าใช้จ่าย ดังนั้นข้อมูลควรถูกถ่ายโอนเป็นชุดแทนที่จะทีละฟิลด์
JNIEnv คือพอยน์เตอร์ไปยังตารางฟังก์ชัน JNI env->FindClass โหลดคลาส Java, env->GetMethodID รับตัวระบุเมธอด, env->CallVoidMethod เรียกใช้มัน สำหรับสตริงให้ใช้ GetStringUTFChars และ ReleaseStringUTFChars JNI ยังรองรับการอ้างอิงแบบโกลบอลและแบบอ่อนไปยังออบเจกต์ Java
// การส่งอาร์เรย์ไบต์จาก 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 คือการรั่วไหลของการอ้างอิงแบบโกลบอล แต่ละ NewGlobalRef ต้องถูกปล่อยผ่าน DeleteGlobalRef การอ้างอิงแบบโลคัล (ที่ส่งคืนโดย FindClass, NewStringUTF) จะถูกปล่อยอัตโนมัติเมื่อกลับจากฟังก์ชันดั้งเดิม สำหรับการเรียกที่เข้มข้น ให้ใช้ PushLocalFrame / PopLocalFrame
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 จัดหาให้โดยอัตโนมัติระหว่างบิลด์
# 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 คือตัวจัดการแพ็กเกจ C++ จาก Microsoft ที่รองรับ Android NDK เป็นแพลตฟอร์มเป้าหมาย ผ่าน vcpkg สามารถติดตั้ง Boost, OpenCV, SQLite, nlohmann-json และไลบรารีอื่น ๆ ที่คอมไพล์สำหรับ Android ABI Vcpkg รวมกับ CMake ผ่าน CMAKE_TOOLCHAIN_FILE
C++ ให้ประสิทธิภาพสูงสุดบนอุปกรณ์มือถือด้วยการคอมไพล์เป็นโค้ด ARM ดั้งเดิมและการไม่มีตัวเก็บขยะ ตามการทดสอบของ Google (Android Performance Patterns, 2024) โค้ด JNI ใน C++ ทำงานเร็วกว่าโค้ด Java ที่เทียบเท่า 3–10 เท่าสำหรับงานที่ต้องคำนวณหนัก
ปัจจัยหลักของประสิทธิภาพ C++ บนแพลตฟอร์มมือถือ: locality ของแคช (การจัดเรียงหน่วยความจำต่อเนื่อง), คำสั่ง SIMD NEON สำหรับ ARM, การสื่อสาร JNI แบบอะซิงโครนัสผ่านคิวข้อความ NEON คือส่วนขยาย SIMD ของ ARM ที่ประมวลผลข้อมูล 128 บิตในคำสั่งเดียว ซึ่งจำเป็นสำหรับการประมวลผลเสียง วิดีโอ และภาพ
// การประมวลผลอาร์เรย์ 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 จากหน่วยความจำไปยังรีจิสเตอร์ NEON 128 บิต vmulq_f32 คูณทั้ง 4 องค์ประกอบด้วย 0.5 ในหนึ่งรอบ vst1q_f32 เก็บผลลัพธ์กลับ หากไม่มี SIMD ลูปเดียวกันจะต้องคูณ 4 ครั้งตามลำดับ — NEON ให้ความเร็วเพิ่มขึ้นถึง 4x สำหรับการดำเนินการดังกล่าว
| การดำเนินการ | C++ (ม.ว.) | Java/Kotlin (ม.ว.) | ความเร็วที่เพิ่มขึ้น |
|---|---|---|---|
| การประมวลผลภาพ 1920x1080 | 12 | 45 | 3.75x |
| การแปลงฟูเรียร์อย่างเร็ว (FFT) | 8 | 34 | 4.25x |
| การเข้ารหัส AES-256 ของบล็อก 1MB | 3 | 18 | 6x |
| การบีบอัดข้อมูล ZLIB | 5 | 22 | 4.4x |
ข้อผิดพลาดแรกและอันตรายที่สุดคือ การรั่วไหลของหน่วยความจำ ทุก new ต้องมี delete, ทุก new[] ต้องมี delete[] บนอุปกรณ์มือถือที่มี RAM จำกัด การรั่วไหลใด ๆ จะนำไปสู่ OMM (หน่วยความจำหมด) และแอปขัดข้อง ใช้ 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 ns หากคุณประมวลผลอาร์เรย์ 10,000 องค์ประกอบทีละตัวผ่าน JNI ค่าใช้จ่ายจะมากกว่างานที่มีประโยชน์ ส่งอาร์เรย์ทั้งหมดในครั้งเดียวและประมวลผลฝั่ง C++
ปัญหาเกี่ยวกับมัลติเธรด เป็นข้อผิดพลาดทั่วไปอีกอย่าง C++ สามารถเริ่ม std::thread ได้ แต่ JNI สามารถเข้าถึงได้จากเธรดที่สร้างโดย Java เท่านั้น ในการเรียกเมธอด Java จากเธรด C++ ให้ใช้ AttachCurrentThread / DetachCurrentThread ผ่าน JNI
// การเรียก 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 (Native Development Kit) คือชุดเครื่องมือสำหรับเขียนส่วนต่าง ๆ ของแอปพลิเคชันในภาษา C หรือ C++ ใช้สำหรับงานที่สำคัญด้านประสิทธิภาพ, การพอร์ตไลบรารี C/C++ ไปยัง Android และการนำโค้ดข้ามแพลตฟอร์มสำหรับ Unity และ Unreal Engine ไปใช้
ใน Unity โค้ดตรรกะเกมเขียนด้วย C# แต่ C++ ใช้ร่วมกับ Android NDK สำหรับปลั๊กอิน, การเร่งด้วยฮาร์ดแวร์, การพอร์ตไลบรารี C++ ที่กำหนดเอง และการรวม SDK ดั้งเดิมสำหรับโฆษณาและการวิเคราะห์
CMakeLists.txt อธิบายไฟล์ต้นฉบับ, ไลบรารี และแฟล็กการคอมไพล์ การกำหนดค่าขั้นต่ำประกอบด้วย add_library สำหรับบิลด์ .so และ target_link_libraries สำหรับเชื่อมโยง log ของ Android และไลบรารีระบบอื่น ๆ
JNI (Java Native Interface) คือชั้นระหว่างโค้ด Java/Kotlin ของแอป Android และไลบรารี C++ หาก C++ ถูกเรียกจาก Java JNI เป็นสิ่งจำเป็น คุณสามารถเขียนโค้ด C++ ทั้งหมดผ่าน NDK ได้ แต่จุดเข้าส่วนใหญ่คือ Activity ของ Java ที่เรียกฟังก์ชันดั้งเดิม
C++ เหมาะสมสำหรับเกม, การประมวลผลเสียง/วิดีโอแบบเรียลไทม์, คอมพิวเตอร์วิทัศน์, การเข้ารหัส, การจำลองทางฟิสิกส์ และการพอร์ตไลบรารีจากแพลตฟอร์มอื่น สำหรับแอปพลิเคชัน UI ทั่วไป Kotlin มีประสิทธิภาพและง่ายกว่า
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ