Sık karşılaşılan sorunlar ve çözümleri

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.