2015. 12. 24. 11:15 devel/android
java nested class jni 의 c로 전달하는 방법 및 java 메서드 호출
java class definition
package com.forge.blacksmith;
public class ironworks { enum qctest { FAIL, PASS }; class weapon { class knife { public int price; public byte serialnumber; } class sword { private qctest result; public void setQcPass() { result = qctest.PASS; } public void setQcFail() { result = qctest.FAIL; } public qctest getQcResult() { return result; } } public knife[] poisoned; public sword[] twohanded; }
}
jni code
jint Java_com_forge_blacksmith_ironworks_WeaponTest( JNIEnv* env, jobject thiz, jobject weapon ) { jclass jclsWeapon = (*env)->GetObjectClass(env, weapon); if(!jclsWeapon || (*env)->ExceptionCheck(env)) {
__android_log_print(ANDROID_LOG_INFO, "jni@debug", "%s, %d", __func__, __LINE__); return JNI_ERR; } jfieldID jfidPoisoned = (*env)->GetFieldID(env, jclsWeapon, "poisoned",
"[com/forge/blacksmith/ironworks$weapon"); if(!jfidPoisoned) { __android_log_print(ANDROID_LOG_INFO, "jni@debug", "check your Full Qualified Class Name"); return -EFAULT; }
// 이후부터 null 검사 생략
jobjectArray jobjarrPoisoned = (*env)->GetObjectField(env, weapon, jfidPoisoned); //class weapon jobject jobjPoisoned = (*env)->GetObjectArrayElement(env, jobjarrPoisoned, 0); //knife[0] poisoned jclass jclsPoisoned = (*env)->GetObjectClass(env, jobjPoisoned); // jfieldID jfidPrice = (*env)->GetFieldID(env, jclsPoisoned, "price", "I"); (*env)->SetIntField(env, jobjPoisoned, jfidPrice, 800); jfieldID jfidTwohanded = (*env)->GetFieldID(env, jclsWeapon, "twohanded",
"[Lcom/forge/blacksmith/ironworks$weapon;");
/*
버그인지 안드로이드 에뮬레이터에서는 FQCN을 아래로 적어도 정상 동작했다
"[com/forge/blacksmith/ironworks$weapon");
*/ jobjectArray jobjarrTwohanded = (*env)->GetObjectField(env, weapon, jfidTwohanded); jobject jobjTwohanded = (*env)->GetObjectArrayElement(env, jobjarrTwohanded, 0); jclass jclsTwohanded = (*env)->GetObjectClass(env, jobjTwohanded); jmethodID jmthdTwohanded = (*env)->GetMethodID(env, jclsTwohanded, "setQcPass", "()V"); (*env)->CallVoidMethod(env, jobjTwohanded, jmthdTwohanded); }
java code
package com.forge.blacksmith;
weapon box = new weapon(); box.poisoned = new weapon.knife[2]; box.twohanded = new weapon.sword[3]; box.poisoned[0].price = 500; box.twohanded[2].setQcFail();
이후 jni 함수 호출, 인자는 box 객체로 넘기면 끝
jni를 본의 아니게 하는 중
android studio 에서 이것저것 해보는데 재미있는거 같다
member 변수의 private, public는 적당히 바꿔서 사용하면 될듯(c 입장에서는 상관없다)
java의 enum은 c의 enum과 너무 다르기 때문에 Set자료형Field 함수를 사용해서 기록하는걸 안하는게 낫다
왜냐면 java는 enum이 진짜 enum이라서 아래와 같은 code가 작동하지 않는다
그래서 method call하는게 정답
enum test { A, B };
if( test.A == 0 } -> 불가능
단순 객체 가져오는 code는 많은데 java 중첩 클래스를 c로 가져오는 것에 대해 설명이 없어서 끄적여봄
맞게 한건지는 모르겠다 -.-;;
기타 ibm developerworks의 jni 문서링크
꽤 이런저런 자세한 내용이 많아 읽어봄직하다
http://www.ibm.com/developerworks/library/j-jni/
'devel > android' 카테고리의 다른 글
Android Sensor HAL Porting Guide? (0) | 2017.03.18 |
---|---|
안드로이드 센서 프레임워크 분석#2 - Android Sensor Service Porting (0) | 2017.03.18 |
안드로이드 센서 프레임워크 분석#1 - Android Sensor Service Porting (0) | 2016.12.24 |
JNI types and Data structures - signatures (0) | 2016.12.07 |
android studio 1.5 에서 jni debug 할 때 ldLibs 설정하는 방법 (0) | 2015.12.07 |