Bu belgede, NDK'yı kullanırken karşılaşabileceğiniz en sık karşılaşılan hata olmayan hataların ve çözümlerinin (varsa) kısmi listesi verilmiştir.
_FILE_OFFSET_BITS=64
eski API düzeyleriyle kullanılıyor
Birleştirilmiş üstbilgilerden önce NDK, _FILE_OFFSET_BITS=64
'yi desteklemiyordu. Uygulamanızı oluştururken tanımladıysanız bu, sessizce yoksayılır. _FILE_OFFSET_BITS=64
seçeneği artık birleştirilmiş başlıklarla desteklenmektedir, ancak Android'in eski sürümlerinde çok az sayıda off_t
API'si off64_t
varyantı olarak sunulmaktaydı. Bu nedenle, bu özelliğin eski API düzeyleriyle kullanılması daha az işlevin kullanılmasına neden olur.
Bu sorun r16 blog yayınında ve biyonik dokümanlarda ayrıntılı olarak açıklanmıştır.
Sorun: Derlemeniz, minSdkVersion
içinde bulunmayan API'leri istiyor.
Çözüm: _FILE_OFFSET_BITS=64
özelliğini devre dışı bırakın veya minSdkVersion
değerinizi yükseltin.
mmap
tanımının açıklanmamış veya örtülü tanımı
C++'ta aşağıdaki hatayı görebilirsiniz:
hata: beyan edilmemiş "mmap" tanımlayıcısı kullanımı
veya C'de aşağıdaki hata vardır:
uyarı: "mmap" işlevinin örtülü bildirimi C99'da geçersiz
_FILE_OFFSET_BITS=64
kullanılması, C kitaplığına mmap
yerine mmap64
talimatı verir. mmap64
, android-21
tarihine kadar kullanılamıyordu. minSdkVersion
değeriniz 21'den düşükse C kitaplığı _FILE_OFFSET_BITS=64
ile uyumlu bir mmap
içermediğinden işlev kullanılamaz.
minSdkVersion
, cihazın API düzeyinden daha yüksek bir değere ayarlandı
NDK ile temel oluşturduğunuz API seviyesi, compileSdkVersion
'in Java'dakinden çok farklı bir anlamı vardır. NDK API düzeyi, uygulamanızın minimum desteklenen API düzeyidir. ndk-build'de bu sizin APP_PLATFORM
ayarınızdır. CMake ile bu: -DANDROID_PLATFORM
.
İşlevlere yapılan referanslar genellikle kitaplıklar ilk çağrıldıklarında değil de yüklendiğinde çözümlendiği için her zaman mevcut olmayan API'lere referansta bulunamaz ve API düzeyi kontrolleriyle kullanımlarını koruyamazsınız. Bunlardan bahsediliyorsa mevcut olmaları gerekir.
Sorun: NDK API düzeyiniz, cihazınız tarafından desteklenen API'den daha yüksek.
Çözüm: NDK API düzeyinizi (APP_PLATFORM
), uygulamanızın desteklediği minimum Android sürümüne ayarlayın.
Derleme Sistemi | Ayar |
---|---|
ndk-build | APP_PLATFORM |
Yapay Zeka | ANDROID_PLATFORM |
externalNativeBuild | android.minSdkVersion |
Diğer derleme sistemleri için NDK'yı diğer derleme sistemleriyle kullanma bölümüne bakın.
__aeabi
simgesi bulunamadı
Aşağıdaki mesaj:
UnsatisfiedLinkError: dlopen başarısız oldu: "
__aeabi_memcpy
" sembolü bulunamıyor
olası çalışma zamanı hatalarına bir örnektir. Bu hatalar, yerel kitaplıklarınızı yüklemeye çalıştığınızda günlükte görünür. Simge şunlardan herhangi biri olabilir: __aeabi_*
; __aeabi_memcpy
ve __aeabi_memclr
en yaygın olanlarıdır.
Bu sorun, Sorun 126'da belgelenmiştir.
rand
sembolü bulunamadı
Aşağıdaki hata günlüğü mesajı için:
UnsatisfiedLinkError: dlopen başarısız oldu: "
rand
" sembolü bulunamıyor
Bu ayrıntılı Stack Overflow yanıtını inceleyin.
__atomic_*
için tanımlanmamış referans
Sorun: Bazı ABI'lerin, atom işlemleri için bazı uygulamalar sağlaması amacıyla libatomic
gerekir.
Çözüm: Bağlantı oluştururken -latomic
ekleyin.
Aşağıdaki hata mesajı için:
hata: Tanımlanmamış "
__atomic_exchange_4
" başvurusu
buradaki gerçek sembol, önünde __atomic_
olan herhangi bir şey olabilir.
Kütüphane sınırlarının dışında çalışmayan RTTI/istisnalar
Sorun: Paylaşılan kitaplık sınırları dışına çıkarıldığında istisnalar yakalanmıyor veya dynamic_cast
başarısız oluyor.
Çözüm: Türlerinize bir anahtar işlevi ekleyin. Anahtar işlevi, bir tür için birinci saf olmayan, satır dışı sanal işlevdir. Örnek için Sorun 533 ile ilgili tartışmaya bakın.
C++ ABI, iki nesnenin aynı türde olduğunu ancak type_info
işaretçilerinin aynı olması durumunda belirtir. İstisnalar yalnızca, yakalamanın type_info
öğesi bildirilen istisnayla eşleşirse yakalanabilir. Aynı kural dynamic_cast
için de geçerlidir.
Bir türün anahtar işlevi yoksa typeinfo
zayıf simge olarak yayınlanır ve kitaplıklar yüklendiğinde eşleme türü bilgileri birleştirilir. Yürütülebilir dosya yüklendikten sonra kitaplıkları dinamik olarak yüklerken (diğer kelimelerle dlopen
veya System.loadLibrary
aracılığıyla), yükleyicinin yüklenen kitaplıkların tür bilgilerini birleştirmesi mümkün olmayabilir. Böyle bir durumda, iki tür
eşit olarak kabul edilmez.
Eşleşmeyen önceden oluşturulmuş kitaplıkları kullanma
Uygulamanızda genellikle üçüncü taraf kitaplıkları olan önceden oluşturulmuş kitaplıkları kullanmak biraz daha dikkatli olmanızı gerektirir. Genel olarak aşağıdaki kurallara dikkat edin:
Sonuçta elde edilen uygulamanın minimum API düzeyi, uygulamanın tüm kitaplıklarının maksimum
minSdkVersion
değeridir.minSdkVersion
16 ise ancak 21'e dayalı önceden oluşturulmuş bir kitaplık kullanıyorsanız sonuçta elde edilen uygulamanın minimum API düzeyi 21 olur. Önceden oluşturulmuş kitaplık statikse bu kurala uyulmaması, derleme sırasında görünür ancak önceden oluşturulmuş paylaşılan kitaplıklar için çalışma zamanına kadar görünmeyebilir.Tüm kitaplıklar aynı NDK sürümüyle oluşturulmalıdır.
Bozulmalar nadiren yaşandığı için bu kural çoğundan biraz daha esnektir ancak NDK'nın farklı ana sürümleriyle oluşturulmuş kitaplıklar arasında uyumluluk garanti edilmez. C++ ABI kararlı değildir ve geçmişte değişmiştir.
Birden fazla paylaşılan kitaplığı olan uygulamalar paylaşılan bir STL kullanmalıdır.
Uyuşmayan STL'lerde olduğu gibi, büyük bir özen gösterilerek bunun yol açtığı sorunlar önlenebilir, ancak yalnızca bu sorundan kaçınmak daha iyidir. Bu sorunu önlemenin en iyi yolu uygulamanızda birden fazla paylaşılan kitaplık olmasından kaçınmaktır.