Dokumen ini adalah sebagian daftar non-bug yang paling umum ditemui yang mungkin Anda temukan saat menggunakan NDK, dan solusinya (jika tersedia).
Menggunakan _FILE_OFFSET_BITS=64
dengan API level yang lebih lama
Sebelum header terpadu, NDK tidak mendukung _FILE_OFFSET_BITS=64
. Jika
Anda menentukannya saat mem-build aplikasi, kode tersebut akan otomatis diabaikan. Opsi
_FILE_OFFSET_BITS=64
kini didukung dengan header terpadu, tetapi di
Android versi lama sangat sedikit off_t
API yang tersedia sebagai varian off64_t
. Oleh karena itu, penggunaan fitur ini dengan API level lama akan menghasilkan
ketersediaan fungsi yang lebih sedikit.
Masalah ini dijelaskan secara detail dalam postingan blog r16 dan dalam dokumentasi bionic.
Masalah: Build Anda meminta API yang tidak ada di
minSdkVersion
.
Solusi: Nonaktifkan _FILE_OFFSET_BITS=64
atau naikkan minSdkVersion
.
Definisi mmap
yang tidak dideklarasikan atau implisit
Anda mungkin melihat error berikut di C++:
error: penggunaan ID yang tidak dideklarasikan 'mmap'
atau error berikut di C:
peringatan: deklarasi implisit fungsi 'mmap' tidak valid di C99
Penggunaan _FILE_OFFSET_BITS=64
menginstruksikan library C untuk menggunakan mmap64
, bukan
mmap
. mmap64
tidak tersedia sampai android-21
. Jika nilai minSdkVersion
Anda lebih rendah dari 21, library C tidak berisi mmap
yang
kompatibel dengan _FILE_OFFSET_BITS=64
, sehingga fungsi tidak tersedia.
minSdkVersion
disetel lebih tinggi dari API level perangkat
API level yang Anda buat dengan NDK memiliki arti yang sangat berbeda dari
yang dilakukan compileSdkVersion
untuk Java. API Level NDK adalah API level minimum
yang didukung aplikasi Anda. Di ndk-build, ini adalah setelan APP_PLATFORM
Anda. Dengan
CMake, ini adalah -DANDROID_PLATFORM
.
Karena referensi ke fungsi biasanya diselesaikan saat library dimuat, bukan saat pertama kali dipanggil, Anda tidak dapat mereferensikan API yang tidak selalu ada dan menjaga penggunaannya saat melakukan pemeriksaan API level. Jika disebutkan, semua harus ada.
Masalah: API level NDK Anda lebih tinggi daripada API yang didukung oleh perangkat Anda.
Solusi: Setel API level NDK (APP_PLATFORM
) ke versi minimum
Android yang didukung aplikasi Anda.
Sistem Build | Setelan |
---|---|
ndk-build | APP_PLATFORM |
CMake | ANDROID_PLATFORM |
externalNativeBuild | android.minSdkVersion |
Untuk sistem build lainnya, lihat Menggunakan NDK dengan sistem build lain.
Tidak dapat menemukan Simbol __aeabi
Pesan berikut:
UnsatisfiedLinkError: dlopen gagal: tidak dapat menemukan simbol "
__aeabi_memcpy
"
adalah salah satu contoh kemungkinan error runtime. Error ini muncul di log saat
Anda mencoba memuat library native. Simbol tersebut dapat berupa salah satu dari
__aeabi_*
; __aeabi_memcpy
dan __aeabi_memclr
tampaknya yang paling umum.
Masalah ini didokumentasikan dalam Masalah 126
Tidak dapat menemukan simbol rand
Untuk pesan log error berikut:
UnsatisfiedLinkError: dlopen gagal: tidak dapat menemukan simbol "
rand
"
Lihat jawaban Stack Overflow yang mendetail ini.
Referensi yang tidak ditetapkan ke __atomic_*
Masalah: Beberapa ABI memerlukan libatomic
untuk menyediakan beberapa implementasi untuk
operasi atomik.
Solusi: Tambahkan -latomic
saat menautkan.
Untuk pesan error berikut:
error: referensi tidak ditentukan untuk '
__atomic_exchange_4
'
di sini simbol yang sebenarnya mungkin berupa apa pun yang diawali dengan __atomic_
.
RTTI/pengecualian tidak berfungsi di seluruh batas library
Masalah: Pengecualian tidak tertangkap saat ditampilkan di seluruh batas
library bersama, atau dynamic_cast
gagal.
Solusi: Tambahkan fungsi kunci ke jenis. Fungsi kunci adalah fungsi virtual pertama yang tidak murni dan tidak wajar untuk jenis. Sebagai contoh, lihat diskusi tentang Masalah 533.
C++ ABI menyatakan bahwa dua objek memiliki jenis if yang sama dan
hanya jika pointer type_info
-nya sama. Pengecualian hanya dapat ditangkap
jika type_info
untuk tangkapan cocok dengan pengecualian yang ditampilkan. Aturan yang sama
berlaku untuk dynamic_cast
.
Saat jenis tidak memiliki fungsi kunci, typeinfo
-nya dihasilkan sebagai simbol
lemah dan info jenis yang cocok digabungkan saat library dimuat. Saat
memuat library secara dinamis setelah library yang dapat dieksekusi dimuat (dengan
kata lain, melalui dlopen
atau System.loadLibrary
), loader mungkin tidak dapat
menggabungkan info jenis untuk library yang dimuat. Jika hal ini terjadi,
kedua jenis tersebut tidak dianggap sama.
Menggunakan library bawaan yang tidak cocok
Menggunakan library bawaan—ini biasanya adalah library pihak ketiga—dalam aplikasi Anda harus lebih berhati-hati. Secara umum, perhatikan aturan berikut:
API level minimum aplikasi yang dihasilkan adalah maksimum
minSdkVersion
dari semua library aplikasi.Jika
minSdkVersion
Anda versi 16, tetapi menggunakan library bawaan yang di-built dengan versi 21, API level minimum aplikasi yang dihasilkan adalah 21. Ketidakpatuhan ini akan muncul pada waktu build jika library bawaan bersifat statis, tetapi mungkin tidak akan muncul hingga waktu proses untuk library bersama bawaan.Semua library harus dibuat dengan versi NDK yang sama.
Aturan ini sedikit lebih fleksibel daripada sebagian besar aturan karena kerusakan jarang terjadi, tetapi kompatibilitas antara library yang di-build dengan versi utama NDK yang berbeda tidak dijamin. C++ ABI tidak stabil dan telah berubah sebelumnya.
Aplikasi dengan beberapa library bersama harus menggunakan STL bersama.
Seperti STL yang tidak cocok, masalah yang disebabkan oleh hal ini dapat dihindari jika ditangani dengan sangat hati-hati, tetapi lebih baik menghindari masalah tersebut. Cara terbaik untuk menghindari masalah ini adalah tidak memiliki beberapa library bersama di aplikasi Anda.