2016-08-15 6 views
2

ネイティブCコードからJavaを呼び出す際に問題があります。具体的には、適切なクラスIDとメソッドIDを確保することが困難でした。私は当初、メンバー関数ではなく静的メソッドでいくつかの運があったが、私は両方を試した。AndroidのC++からjavaメソッドを呼び出すクラスIDとメソッドID

以下に示すように、単純なJavaブール関数retTrueは正常に戻りますが、データ配列を正しく渡すことができません。

静的jmethodID midSetRTS、midClearRTS、midClearRTSb、midTX、midSniffRx、midSniffTx、midClose; static jmethodID midgetFTDIDevice;主な活動から

static JavaVM *g_VM; 
static jclass cls; 
static jmethodID javaMethodRef; 


JNIEXPORT jstring JNICALL Java_com_example_rick_myjni_MyNDK_getMyString(JNIEnv *env, jobject jobj) { 
    __android_log_print(ANDROID_LOG_VERBOSE, TAG, "Hello from native code"); 

    env->GetJavaVM(&g_VM); 
    __android_log_print(ANDROID_LOG_VERBOSE, TAG, "Attaching to VM thread."); 

    jint rs = g_VM->AttachCurrentThread((JNIEnv**)&env,NULL); 
    if(rs == JNI_OK) 
     __android_log_print(ANDROID_LOG_VERBOSE, TAG, "Attached"); 
    else 
     __android_log_print(ANDROID_LOG_VERBOSE, TAG, "Failed to Attach"); 

    static int once = 1; 
    if (once) { 
     jclass dataClass = env->FindClass("com/example/rick/myjni/MainActivity"); 
     if (env->ExceptionCheck()) { 
      return (*env).NewStringUTF("Exception"); 
     } 

     cls = (jclass) env->NewGlobalRef(dataClass); 
     if (env->ExceptionCheck()) { 
      return (*env).NewStringUTF("Exception"); 
     } 

     javaMethodRef = env->GetStaticMethodID(cls, "retTrue", "()Z"); 
     __android_log_print(ANDROID_LOG_VERBOSE, TAG, "cls: %d javaMethodRef %d", (int)cls, (int)javaMethodRef); 
     midTX = env->GetStaticMethodID(cls, "TX", "([BI)Z"); 
     __android_log_print(ANDROID_LOG_VERBOSE, TAG, "cls: %d midTX %d", (int)cls, (int)midTX); 

     if (env->ExceptionCheck()) { 
      return (*env).NewStringUTF("Exception"); 
     } 
     once = 0; 
    } 
    bool success = true; 
    jbyte txTestMsg[] = {0x18, 0x00, 0x0D, 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0xFF,0x00,0xFF}; 
    jint len = 16; 
    __android_log_print(ANDROID_LOG_VERBOSE, TAG, "len: %d txTestMsg: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x ", len, 
     txTestMsg[0], txTestMsg[1], txTestMsg[2], txTestMsg[3], 
     txTestMsg[4], txTestMsg[5], txTestMsg[6], txTestMsg[7], 
     txTestMsg[8], txTestMsg[9], txTestMsg[10], txTestMsg[11], 
     txTestMsg[12], txTestMsg[13], txTestMsg[14], txTestMsg[15]); 

    success = env->CallStaticBooleanMethod(cls, javaMethodRef); 
    __android_log_print(ANDROID_LOG_VERBOSE, TAG, "Call retTrue succces: %d",success); 

    COFFEE_TRY() { 
     success = env->CallStaticBooleanMethod(cls, midTX, txTestMsg, len); 
     if (env->ExceptionCheck()) { 
       return (*env).NewStringUTF("Exception"); 
     } 
    } 
    COFFEE_CATCH() { 
     coffeecatch_throw_exception(env); 
    } COFFEE_END(); 

    if(success) 
     return (*env).NewStringUTF("Success"); 
    else 
     return (*env).NewStringUTF("Failure"); 
} 

public class MainActivity extends AppCompatActivity { 
    private static final String TAG = "MainActivity"; 
    ... 

    public static boolean TX(byte[] data, int len) 
    { 
     Log.i(TAG,"MainActivity:TX length " + len + " data: " + data.toString()); 
     return myFTDIdevice.TX(data,len); 
    } 

    public static boolean retTrue() 
    { 
     Log.i(TAG,"MainActivity:reTrue"); 
     return true; 
    } 

注アンドロイドログファイルの出力:私は私の頭脳を吹き消すしたい

08-17 14:55:49.827 12389-12432/com.example.rick.myjni V/MyJNI: Hello from native code 
08-17 14:55:49.827 12389-12432/com.example.rick.myjni V/MyJNI: Attaching to VM thread. 
08-17 14:55:49.827 12389-12432/com.example.rick.myjni V/MyJNI: Attached 
08-17 14:55:49.827 12389-12432/com.example.rick.myjni V/MyJNI: cls: 1050382 javaMethodRef -2012626856 
08-17 14:55:49.827 12389-12432/com.example.rick.myjni V/MyJNI: cls: 1050382 midTX -2012627024 
08-17 14:55:49.827 12389-12432/com.example.rick.myjni V/MyJNI: len: 16 txTestMsg: 18 0 d 1 2 3 4 5 6 7 8 9 a ffffffff 0 ffffffff 
08-17 14:55:49.827 12389-12432/com.example.rick.myjni I/MainActivity: MainActivity:reTrue 
08-17 14:55:49.827 12389-12432/com.example.rick.myjni V/MyJNI: Call retTrue succces: 1 
08-17 14:55:49.832 12389-12432/com.example.rick.myjni A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0xdead4321 in tid 12432 (Thread-9233) 
08-17 14:55:49.872 12389-12396/com.example.rick.myjni W/art: Suspending all threads took: 13.880ms 
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65] JNI DETECTED ERROR IN APPLICATION: JNI NewStringUTF called with pending exception 'java.lang.Error' thrown in java.lang.String com.example.rick.myjni.MyNDK.getMyString():-2 
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65]  in call to NewStringUTF 
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65]  from java.lang.String com.example.rick.myjni.MyNDK.getMyString() 
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65] "Thread-9233" prio=5 tid=16 Runnable 
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65] | group="main" sCount=0 dsCount=0 obj=0x12f7f7c0 self=0xb47c4800 
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65] | sysTid=12432 nice=0 cgrp=default sched=0/0 handle=0xb4509c00 
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65] | state=R schedstat=(0 0 0) utm=6 stm=5 core=1 HZ=100 
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65] | stack=0x9ce0c000-0x9ce0e000 stackSize=1036KB 
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65] | held mutexes= "mutator lock"(shared held) 
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65] native: #00 pc 00004e6c /system/lib/libbacktrace_libc++.so (UnwindCurrent::Unwind(unsigned int, ucontext*)+23) 
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65] native: #01 pc 00003665 /system/lib/libbacktrace_libc++.so (Backtrace::Unwind(unsigned int, ucontext*)+8) 
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65] native: #02 pc 00266509 /system/lib/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, char const*, art::mirror::ArtMethod*)+84) 
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65] native: #03 pc 0024857f /system/lib/libart.so (art::Thread::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const+158) 
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65] native: #04 pc 000b4e83 /system/lib/libart.so (art::JniAbort(char const*, char const*)+610) 
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65] native: #05 pc 000b55a9 /system/lib/libart.so (art::JniAbortF(char const*, char const*, ...)+68) 
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65] native: #06 pc 000b8873 /system/lib/libart.so (art::ScopedCheck::ScopedCheck(_JNIEnv*, int, char const*)+1342) 
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65] native: #07 pc 000c1665 /system/lib/libart.so (art::CheckJNI::NewStringUTF(_JNIEnv*, char const*)+28) 
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65] native: #08 pc 0000162f /data/app/com.example.rick.myjni-2/lib/arm/libMyLibrary.so (_JNIEnv::NewStringUTF(char const*)+10) 
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65] native: #09 pc 00001845 /data/app/com.example.rick.myjni-2/lib/arm/libMyLibrary.so (Java_com_example_rick_myjni_MyNDK_getMyString+516) 
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65] native: #10 pc 000162e7 /data/data/com.example.rick.myjni/cache/slice-slice_5-classes.dex (Java_com_example_rick_myjni_MyNDK_getMyString__+82) 
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65] at com.example.rick.myjni.MyNDK.getMyString(Native method) 
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65] at com.example.rick.myjni.MainActivity$3.run(MainActivity.java:150) 
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65] at java.lang.Thread.run(Thread.java:818) 
08-17 14:55:49.902 12389-12432/com.example.rick.myjni A/art: sart/runtime/check_jni.cc:65] 
+0

jclassをintにキャストアウトすると、GetObjectClassから返された構造体へのポインタが出力されます。同じクラスのために毎回同じものが返されるとは限りませんので、ポインタは一致しません。また、env-> GetObjectClass(jobj); myNDKクラスはネイティブ関数が呼び出される関数なので返されますが、呼び出す関数はMainActivityにあり、したがってエラーです。 – samgak

+0

私は、この例でclsへの参照のそれぞれから派生したMIDを呼び出そうとしましたが、それらはすべて失敗します。私は、静的ヘルパーメソッドをmyNDKクラスに追加して、それらも呼び出そうとしました。 また、ポインタの値が同じでない(キャストされた)同じクラスを指しているのはなぜですか? –

答えて

1

OMG。メソッドIDやクラスIDとは何の関係もありませんが、引数は渡されます。私は渡すことができるようにCで有効なJava配列をインスタンス化しなければなりませんでした。

bool success = true; 
    jbyte temptxTestMsg[] = {0x18, 0x00, 0x0D, 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0xFF,0x00,0xFF}; 
    jint len = 16; 

    jbyteArray txTestMsg = env->NewByteArray(len); 
    env->SetByteArrayRegion(txTestMsg,0,len,temptxTestMsg); 
関連する問題