2011-06-23 10 views
5

Sanırım sorunun çoğunu bu konudaki başlığa sığdırmayı başardım!JNI - Temel Java Nesneleri (Boolean) temsil eden jobject öğesinin yerel temel türlerine dönüştürülmesi (boole)

benim yerel C Java dan bir nesne geri çekiyorum ++ kodu:

jclass boolClass = env->FindClass("java/lang/Boolean"); 
if(env->IsInstanceOf(valueObject, boolClass) == JNI_TRUE) { } 
: Benim dönüş nesnesi Hava kontrol etmek için

jobject valueObject = env->CallObjectMethod(hashMapObject, hashMapGetMID, keyObject); 

Mümkün gibi bir şey kullanarak yerel türlerinden biridir

Şimdi, bir Boolean olduğunu bildiğim bir işim var (B notu için B) - Soru şu ki, en verimli yöntem (yerel kodumdaki iş parçacığım var) bool. Typecasting işe yaramaz, bu da mantıklı.

Yukarıdaki örnek bir Boolean olmasına rağmen Karakter -> char, Short-> short, Integer-> int, Float-> float, Double-> double'ı da dönüştürmek istiyorum.

(ben bunu uyguladıktan sonra ben bunu yapar bir cevap yayınlayacağız Boolean.booleanValue())

+0

Neden Java kodunda sadece typecasting ve unboxing işlemek değil? –

cevap

5

İki seçeneğiniz var.

Seçenek # 1 kendi yanıtınızda yazdığınız şeydir: ilkel değeri ayıklamak için her sınıf için tanımlanan genel yöntemi kullanın.

Seçenek # 2 daha hızlıdır, ancak kesinlikle yasal değildir: doğrudan iç alana erişin. Boole için bu Boolean.value olurdu. Her bir ilkel kutu sınıfı için "değer" alanı için bir alan kimliğiniz vardır ve sadece alanı doğrudan okuyorsunuz. (JNI özel olarak ilan ettiği gerçeğini neşeyle duyar. Ayrıca "nihai" alanlara yazabilir ve "gerçekten kötü fikir" kategorisine giren başka şeyler de yapabilirsiniz.)

"Değer" alanının adı olası değil Bu değişmek için serileştirme kırılır. Bu yüzden resmen bu tavsiye edilmez, ancak pratikte ihtiyacınız varsa bunlardan kurtulabilirsiniz.

Her iki durumda da jmethodID/jfieldID değerlerini önbelleğe almalısınız, her seferinde bakmadıkça (aramalar nispeten pahalıdır).

Kutu sınıfları "son" olduğu için IsInstanceof yerine daha az pahalı IsSameObject işlevini de kullanabilirsiniz. Bu, valueObject'in sınıfını almak için ekstra bir GetObjectClass çağrısı yapılmasını gerektirir, ancak bunu yalnızca çeşitli karşılaştırmalarınızdan önce yapmanız gerekir.

BTW, "char" kullanımınıza dikkat edin. Yukarıdaki örnekte, CallCharMethod (16 bit UTF-16 değeri) sonucunu bir char'e (8 bitlik bir değere) döküyorsunuz. Unutma, char!= jchar (geniş chars için bir şekilde yapılandırılmadıkça), uzun! = jlong ​​(64-bit long'lar ile derlemedığınız sürece).

+0

Harika cevap teşekkür ederim! Ben sadece düz bilmiyorum yararlı bilgiler. Burada önerdiğiniz veya denenmiş ve test edilen "Kan, Ter ve Gözyaşları" yaklaşımı olan spesifik bir kaynak var mı? :) – Graeme

+2

Burada sorduğun gibi şeyler muhtemelen bir kitaptan öğrenilemez. Kendi VM'nizi yazma vaktiniz varsa kesinlikle çok şey öğreneceksiniz; yok, sadece bir sürü kod yaz ve neden bozuk olduğunu anlamaya çalış. :-) – fadden

1

Bu ben artık giriş alırsanız kullanmak için gidiyorum çözümdür. Genelde

if  (env->IsInstanceOf(valueObject, boolClass)   == JNI_TRUE) 
    { 
     jmethodID booleanValueMID = env->GetMethodID(boolClass, "booleanValue", "()Z"); 
     bool booleanValue   = (bool) env->CallBooleanMethod(valueObject, booleanValueMID); 
     addBoolean(key, booleanValue); 
    } 
    else if(env->IsInstanceOf(valueObject, charClass)   == JNI_TRUE) 
    { 
     jmethodID characterValueMID = env->GetMethodID(charClass, "charValue", "()C"); 
     char characterValue   = (char) env->CallCharMethod(valueObject, characterValueMID); 
     addChar (key, characterValue); 
    } 
0

, ben daha iyi performans için jni yazın: Umarım ben bu olabilir düşünüyorum bu zor ama bilerek JNI'yı değildir. Daha iyi performans nasıl elde edilir? Asm, ilkel türleri ve birkaç yöntem çağrısı kullanarak. Ben düşündürmektedir c kullanabileceğiniz yöntem dönüş türü tasarım/C++, böyle jint, jlong, jboolean, jbyte ve jchar vb

yedekli bir işlev çağrısı olarak ve verimsiz ve unmaintainable uygulanmasını yapacak dönüştürün.

+0

Dinamik kod üzerinde performans için gidiyorum. Çalışma zamanında değerler herhangi bir temel tip olabilir - işte bu nedenle, JNI aracılığıyla türünü kontrol etmek ve geri çağırmak zorunda kalmadan, jobject'i boole/char/int vs vs'ye dönüştürmenin en iyi yolunu bulmaya çalışıyorum. – Graeme

+0

Java seviyesinde dinamik ve esnek olmak daha iyidir. Bence de. – qrtt1

+0

Bende! Ama belirli mantık parçalarının nerede yapıldığı konusunda bir seçeneğim yok. – Graeme