2010-01-21 7 views
5

Sadece Android NDK ile çalışmaya başladı ama benim C kodunda bu çağrıyı varken SIGSEGV almaya devam: bulabilirim bütün örneğiAndroid'de JNI için NewObjectArray öğesini çağırırken SIGSEGV'ye neden olabilir?

jobjectArray someStringArray; 
someStringArray = (*env)->NewObjectArray(env, 10, 
(*env)->FindClass(env,"java/lang/String"),(*env)->NewStringUTF(env, "")); 

Baz, yukarıdaki kodun doğru ama almaya devam NewObjectArray satırının yorumlanması durumunda SIGSERGV ve her şey yolunda. Böyle bir soruna neden olabilecek herhangi bir fikrin var mı?

+0

Unutmayın, NDK1.6 kullanıyorum – Ken

cevap

4

doğru görünüyor, bu yüzden yanlış bir şey yaptığınızı tahmin ediyorum. Checkjni ile koştuğunu mu düşünüyorsun? Bunu birden çok satıra ayırmak isteyebilirsiniz: FindClass'ı yapın ve dönüş değerini kontrol edin, NewStringUTF yapın ve dönüş değerini kontrol edin ve sonra NewObjectArray öğesini arayın. btw, NULL son argüman olarak geçmek isteyebilirsiniz; dizinin her öğesi için varsayılan değer olarak boş dizeyi kullanmanın bu kalıbı yaygın olarak kullanılır (sanırım bazı Sun belgelerinden yapıştırılmış olan & kopyasına sahiptir ve oradan yayılmıştır) ancak nadiren kullanışlıdır ve biraz da israflıdır. (ve Java'daki "yeni String [10]" davranışıyla eşleşmiyor.)

2

Muhtemel nedenlerden biri, uzun süreli bir JNI yönteminde VM'nin, yöntem başına çağrı yerel referans yuvaları (normalde Android'de 512 yuva).

FindClass() ve NewStringUTF() işlevleri yerel referanslar atayacağından, uzun bir süredir JNI yönteminde kalırsanız, VM belirli bir yerel referansın geri dönüştürülmesi gerekip gerekmediğini bilmez. Bu nedenle, artık gerekli olmadığında, edinilen yerel referansları serbest bırakmak için DeleteLocalRef() öğesini açıkça çağırmalısınız. Bunu yapmazsanız, "zombi" yerel referansları Sanal Makinedeki yuvaları kaplar ve tüm yerel referans alanlarından çıkarken VM durdurur. Kısa dönemli JNI yönteminde, JNI yönteminden çıkarken tüm yerel referansların geri dönüştürülmesi nedeniyle bu bir sorun olmayabilir.