2012-12-14 5 views
1

이 매우 중요한 세부 사항이 인터넷에서 포괄적 인 연습을 놓치고 있다는 사실에 놀랐습니다. 또는 나는 아마도 최악의 googler입니다. 또는 전혀 바보 같은 프로그래머.JNI 클래스를 인스턴스화하는 방법

나는 최근 몇 달 동안 안드로이드에 대한 작업을 해왔지만 최근에는 JNI를해야한다고 들었다. 내 C 기술은 이미 녹슬 었어. 그러나 나는 이걸 붙잡고 앞으로 나갈 수 없었을 때 따라 잡고있었습니다.

나는 간단한 것을 원해. 내 MainActivity에서 내 기본 메서드 선언은 다음과 같습니다

public native Object createObject();

이 난 그냥 C에서하는 java.lang.Integer 객체를 생성 할 그것을

Object abc = createObject(); 
    Integer num = (Integer) abc; 

을 사용하고, 자바로 전송하고자하는 방법이다. 그것은 어떤 간단

jobject Java_com_example_hellojni_HelloJni_callbackJava(JNIEnv * env, jobject this) 
{ 
    jclass cls = (*env)->FindClass(env, "java/lang/Integer"); 
    jmethodID methodID = (*env)->GetMethodID(env, cls, "<init>", "(I)V"); 
    jint number = 8 ; 
    return (*env)->NewObject(cls, methodID, number); 

} 

(안드로이드 NDK의 R8C) 나는 내 응용 프로그램 충돌 스택 추적, 환영을받을를 얻을 수 없습니다.

12-14 16:10:07.595: D/dalvikvm(302): Trying to load lib /data/data/com.example.hellojni/lib/libhello-jni.so 0x45f3da60 
12-14 16:10:07.625: D/dalvikvm(302): Added shared lib /data/data/com.example.hellojni/lib/libhello-jni.so 0x45f3da60 
12-14 16:10:07.625: D/dalvikvm(302): No JNI_OnLoad found in /data/data/com.example.hellojni/lib/libhello-jni.so 0x45f3da60, skipping init 

12-14 16:10:07.684: W/dalvikvm(302): **JNI WARNING: threadid=1 using env from threadid=0** 
12-14 16:10:07.684: W/dalvikvm(302):    in Lcom/example/hellojni/HelloJni;.callbackJava()V (NewObject) 
12-14 16:10:07.684: I/dalvikvm(302): "main" prio=5 tid=1 NATIVE 
12-14 16:10:07.684: I/dalvikvm(302): | group="main" sCount=0 dsCount=0 s=N obj=0x4001d8e0 self=0xccb0 
12-14 16:10:07.684: I/dalvikvm(302): | sysTid=302 nice=0 sched=0/0 cgrp=default handle=-1345026008 
12-14 16:10:07.684: I/dalvikvm(302): | schedstat=(152515888 582639885 48) 
12-14 16:10:07.684: I/dalvikvm(302): at com.example.hellojni.HelloJni.callbackJava(Native Method) 
12-14 16:10:07.695: I/dalvikvm(302): at com.example.hellojni.HelloJni.onCreate(HelloJni.java:59) 
12-14 16:10:07.695: I/dalvikvm(302): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
12-14 16:10:07.695: I/dalvikvm(302): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) 
12-14 16:10:07.695: I/dalvikvm(302): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 
12-14 16:10:07.695: I/dalvikvm(302): at android.app.ActivityThread.access$2300(ActivityThread.java:125) 
12-14 16:10:07.695: I/dalvikvm(302): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033) 
12-14 16:10:07.695: I/dalvikvm(302): at android.os.Handler.dispatchMessage(Handler.java:99) 
12-14 16:10:07.695: I/dalvikvm(302): at android.os.Looper.loop(Looper.java:123) 
12-14 16:10:07.695: I/dalvikvm(302): at android.app.ActivityThread.main(ActivityThread.java:4627) 
12-14 16:10:07.695: I/dalvikvm(302): at java.lang.reflect.Method.invokeNative(Native Method) 
12-14 16:10:07.695: I/dalvikvm(302): at java.lang.reflect.Method.invoke(Method.java:521) 
12-14 16:10:07.695: I/dalvikvm(302): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
12-14 16:10:07.695: I/dalvikvm(302): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
12-14 16:10:07.695: I/dalvikvm(302): at dalvik.system.NativeStart.main(Native Method) 
12-14 16:10:07.704: E/dalvikvm(302): VM aborting 

도와주세요.

감사

+0

질문에 대답하지는 않지만 Integer.valueOf()를 사용해야합니다. 코멘트를 주신 덕분에 – ignis

+0

@ignis. 그리고 네, JNI 내부에서 클래스를 인스턴스화하는 방법을 찾고 있습니다. 나의 동기는 지금 그것을 배우는 것입니다. –

+0

JNI에서 자바 클래스를 만드는 방법에 대한 예가 많이 있지만, 왜 그런 일을하는 JNI 메쏘드를 작성하고 아무 것도 나를 완전히 이스케이프 (escape)하지 않는다. – EJP

답변

6

나는 내가 NewObject에 대한 인수에 ENV 퍼팅 놓친 JNI

을 통해 좀 더 검색과 연구를 통해 발견 사소한 실수를하고 있었다. 누구나 필요로하는 경우 올바른 코드를 알려주십시오.

jobject Java_com_example_hellojni_HelloJni_createObject(JNIEnv * env, jobject this) 
{ 

    jclass cls = (*env)->FindClass(env, "java/lang/Integer"); 
    jmethodID methodID = (*env)->GetMethodID(env, cls, "<init>", "(I)V"); 
    jobject a=(*env)->NewObject(env,cls, methodID, 5); 
    return a; 
} 
+2

jni가보고 한 오류는 오해의 소지가 있습니다. "limbo"에 영원히 머물러있을 수 있습니다. –

+0

공정하게 VM이 JNIEnv *를 기대하고 있으며 코드가 jclass를 통과하고있었습니다. 이것은 컴파일러 경고를 통해 감지되었을 것입니다. 그러나 jobject가'void *'(C++ 바인딩은 "fake"클래스 계층 구조를가집니다)로 정의 되었기 때문에 C 바인딩과 함께 발생하지는 않습니다. CheckJNI 메시지는 일반적으로 정확하며 간단한 충돌 메시지보다 큰 개선점입니다. – fadden

관련 문제